Generative
Design Avancé

Canvas & JS 101

2024 - 2025

Generaquoi ?

Sujets

  • Savoir mettre en place un canvas.

  • Maitriser les méthodes basiques de dessin du canvas.

  • Apprendre les notions de bases en javascript (manipuler des nombres, boucle, tableau, objet, etc.)

  • Créer un jeu de particules

  • Comment animer ces particules

Objectif ?

Flow Field

Récupérer, créer et ajouter des éléments HTML

Canvas 101

L'élément canvas permet de manipuler des pixels dans notre HTML.

Setup

Première chose à faire: définir notre canvas.

<canvas id="myCanvas"></canvas>
// On récupère une balise canvas existante
const canvas = document.querySelector( '#myCanvas' );

// Soit on le crée et on l'ajoute au DOM
const newCanvas = document.createElement( 'canvas' );
element.append( newCanvas );

Les dimensions

Par défaut, un canvas a une largeur de 300px et une hauteur 150px. On utilise les propriétés width et height de notre canvas pour changer sa taille.

// On change la largeur et la hauteur.
// Inutile de préciser une unité,
// un canvas interprète les valeurs en pixels.
canvas.width = 500;
canvas.height = 500;

Le contexte

Pour pouvoir dessiner quelque chose dans notre canvas, il nous faut une dernière chose: le contexte. Ce dernier est une boîte à outils, qui contiendra nos méthodes.

Il peut être en 2d ou en 3d (=webgl).

const canvas = document.querySelector( '#myCanvas' );

// Charge nos méthodes dans une
// constante "ctx", qui pourra être utilisé
// pour dessiner en 2d.
const ctx = canvas.getContext( '2d' );

Formes & densité

Rectangles

// 👻 Crée un rectangle sans remplissage, sans contour
ctx.rect( x, y, width, height );

// Dessine et rempli
ctx.fillRect( x, y, width, height );

// Dessine et rajoute un contour
ctx.strokeRect( x, y, width, height );
  • x: La position horizontale du coin supérieur gauche

  • y: La position verticale du coin supérieur gauche

  • width: La largeur du rectangle

  • height: La hauteur du rectangle

Densité de pixel

Device Pixel Ratio (ou DPR)

Si votre écran à une densité de pixel plus grande que 1 ( mac, smartphones, ect.), ce que nous avons dessiné est flou, surtout sur les contours.

Il faut voir le canvas comme une balise image: elle est composée de pixels. Et comme une image, si on veut qu'elle soit nette, il faut que sa résolution reflète le nombre de pixel dessiné, multiplié par la densité de pixel de votre écran.

Ex: Sur un écrand de DPR 2, un canvas de 200px doit avoir une résolution de 400px pour être net.

On peut voir que notre canvas à bien les bonnes dimensions comparé à notre dernier exemple. Par contre les carrés sont plus petits. Effectivement 100px sur 300px de largeur cela fait 1/3, par contre avec une densité 2x supérieur cela équivaut à 1/6 (100px sur 600px).

Nous allons donc dire à notre canvas de prendre en compte la densité de l'écran avant de dessiner. On va utiliser la méthode ctx.scale:

Cercles…

// Dessine un cercle
ctx.arc( x, y, radius, startAngle, endAngle, counterclockwise = false );
  • x: La position horizontale du centre

  • y: La position verticale du centre

  • radius: Le rayon du cercle

  • startAngle: L'angle de début (en radian)

  • endAngle: L'angle de fin (en radian)

  • counterclockwise: Optionnel, la direction de l'arc de cercle (false par défaut)

//-- Un tour de cercle
  // deg = 360 ou rad = 2 * Math.PI
  
  //-- Un quart de cercle
  // deg = 90 ou rad = 0.5 * Math.PI
  
  // Fonction pour convertir des radians en degrés
  const radToDeg = ( rad ) => {
    return rad * ( 180 / Math.PI );
  }
  
  // Fonction pour convertir des degrés en radians
  const degToRad = ( deg ) => {
    return deg * ( Math.PI / 180 );
  }

Contrairement au carré, positionner un arc de cercle se fait à partir de son centre. Changeons les coordonnées de notre cercle pour le centrer sur notre carré.

Toolbox

Template v1 Canvas 🎁

Exercices

Manipuler les nombres

Générer un nombre aléatoire

// Retourne un nombre décimal entre 0 et 0.99999…
let randomNumber1 = Math.random();

// Retourne un nombre décimal entre 0 et 9.99999…
let randomNumber2 = Math.random() * 10;

Arrondir un nombre

Avoir un nombre décimal nous permet entre autre d'être précis. Dans certains cas il sera nécessaire d'avoir des nombres entiers.

Ex: accéder aux éléments d'un tableau, éviter les demi-pixels, améliorer les performances, etc.
Math.floor( 10.50 ); // 10
Math.floor( -3.65 ); // -4

Math.ceil( 10.50 );  // 11
Math.ceil( -3.65 );  // -3

Math.round( 10.50 ); // 11
Math.round( -3.50 ); // -3
Math.round( -3.65 ); // -4

Position aléatoire

Taille aléatoire

Boucle simple

for( let i = 0; i < 3; i++ ) {
  console.log( i );
  // 0 pour la première itération
  // 1 pour la seconde
  // 2 pour la dernière
}

Plus de particules

Exercices, again ?