HTML5+JS
Les effets sont créés en utilisant du JavaScript vanilla sur un élément canvas HTML5. Dans cette section, nous couvrirons les bases : dessiner des formes, dessiner par itération, et ajouter du mouvement.
Dessiner des Formes
Section intitulée « Dessiner des Formes »Pour ce tutoriel, j’utiliserai un modèle de lightscript générique :
<head> <meta description="Template"/> <meta publisher="WhirlwindFX" /></head>
<body style="margin: 0; padding: 0;"> <canvas id="exCanvas" width="320" height="200"></canvas></body>
<script> // Get the canvas element from the DOM var c = document.getElementById("exCanvas"); var ctx = c.getContext("2d");
var width = 320; var height = 200; var hue = 0;
function update() { // Code goes here window.requestAnimationFrame(update); }
window.requestAnimationFrame(update);</script>Que vous utilisiez une ou plusieurs lignes, le processus reste le même.
- ctx.beginPath() démarre votre forme
- ctx.moveTo(x, y) définit le premier point
- ctx.lineTo(x, y) définit le point suivant et une ligne vers le premier. Utilisez plusieurs lineTo pour dessiner des formes plus grandes.
- Définissez ctx.strokeStyle et/ou ctx.fillStyle (si la forme est fermée)
- Utilisez ctx.stroke() pour tracer les lignes, et ctx.fill() pour remplir les formes fermées. Il est important de noter que jusqu’à ce point, tout est hypothétique - rien n’est dessiné tant que ces commandes ne sont pas exécutées.
Voici trois exemples utilisant des lignes :
function update() { // One Line ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(30, 170); ctx.strokeStyle = "blue"; ctx.stroke();
// L ctx.beginPath(); ctx.moveTo(80, 30); ctx.lineTo(80, 100); ctx.lineTo(120, 100); ctx.strokeStyle = "blue"; ctx.stroke();
// Filled Triangle ctx.beginPath(); ctx.moveTo(130, 30); ctx.lineTo(130, 100); ctx.lineTo(170, 100); ctx.lineTo(130, 30); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update);}
Il est important de noter l’ordre de dessin ici : le triangle rempli est dessiné en dernier, donc il couvrirait les deux autres formes si elles étaient à la même position. De plus, le contour du triangle est dessiné après le remplissage. Si nous inversions ces étapes, la moitié intérieure du contour serait couverte par le remplissage rouge.
Rectangles
Section intitulée « Rectangles »Les rectangles sont simples et utiles, surtout pour la résolution moyenne d’un clavier RGB. Le processus est similaire au dessin de lignes - remplacez simplement les commandes moveTo et lineTo par rect(x, y, width, height).
function update() { // Basic Square ctx.beginPath(); ctx.rect(30, 30, 75, 75); ctx.strokeStyle = "blue"; ctx.stroke();
// Filled Rectangle ctx.beginPath(); ctx.rect(125, 30, 125, 100); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update); }
Les arcs sont dessinés en faisant tourner un point extérieur autour d’un point central, et peuvent être utilisés pour créer des cercles complets. La commande d’arc est ctx.arc(x, y, radius, start angle, end angle), où les deux mesures d’angle sont données en radians. Contrairement aux rectangles, un arc est dessiné avec l’origine (x, y) au centre de l’arc.
function update() { // Half-circle ctx.beginPath(); ctx.arc(70, 100, 30, 0, Math.PI); ctx.strokeStyle = "blue"; ctx.stroke();
// 3/4 circle ctx.beginPath(); ctx.arc(140, 100, 30, 0, Math.PI * (3/2)); ctx.strokeStyle = "blue"; ctx.stroke();
// Full circle ctx.beginPath(); ctx.arc(210, 100, 30, 0, Math.PI * 2); ctx.strokeStyle = "blue"; ctx.stroke(); ctx.fillStyle = "red"; ctx.fill();
window.requestAnimationFrame(update); }
Comme vous pouvez le voir, les arcs sont dessinés dans le sens des aiguilles d’une montre par défaut. Cela peut être inversé avec un angle de fin inférieur à l’angle de début, ou en ajoutant “true” comme dernier argument à la méthode ctx.arc().
Dessiner par Itération
Section intitulée « Dessiner par Itération »Dessiner trois formes à la main peut facilement prendre vingt lignes de code, donc si vous avez besoin de dessiner cent formes, nous avons besoin d’une approche plus efficace. Les boucles en JavaScript sont un moyen simple de répéter des tâches, et elles peuvent être appliquées au dessin également.
Voici un exemple utilisant une boucle for pour dessiner une rangée de carrés en damier :
function update() {
for(let i = 0; i < 8; i++){
// 1. Create rectangle path and draw the stroke for each. ctx.beginPath(); ctx.rect(i * 20, 20, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 2. If 'i' is even, the fillStyle is black. Otherwise it's white. if(i % 2 == 0){ ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } // 3. Fill the shape after setting the fillStyle. ctx.fill(); }
window.requestAnimationFrame(update); }
Voici un exemple de boucle while pour dessiner une grille en damier. Je vais modifier légèrement la luminosité des carrés noirs et la teinte des carrés blancs à chaque itération en utilisant des littéraux de gabarit.
function update() {
var i = 0;
while(i < 16){
// 1. X and Y calculations with 'row' and 'column' // This operation rounds the result down to the nearest integer. For i = (0-3) the row will be 0, for i = (4-7) the row will be 1, and so on var iRow = Math.floor(i / 4); // This operation finds the remainder after division, limiting column to the (0-3) range. var iCol = i % 4; // Multiply by the square width to find this square's x-origin var ix = iCol * 20; // Multiply by the square height to find this square's y-origin var iy = iRow * 20;
// 2. Path and stroke ctx.beginPath(); ctx.rect(ix, iy, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 3. If the row is even, every other square is filled black. If odd, switch the black squares. Each iteration adds a small amount of the lightness component to the black, and hue to the white. if(iRow % 2 == 0){ if(i % 2 == 0){ // 'Black' ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } else { // 'White' ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } } else { if(i % 2 == 0){ // 'White' ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } else { // 'Black' ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } }
ctx.fill(); i++; }
window.requestAnimationFrame(update); }
Ajouter du Mouvement
Section intitulée « Ajouter du Mouvement »Les animations dans le canvas ne sont limitées que par votre imagination et vos connaissances mathématiques. Si vous vous sentez peu sûr en trigonométrie ou géométrie, je vous recommande de faire quelques recherches légères pour pousser vos compétences au niveau supérieur. Dans les prochains exemples, je vais prendre un cercle stationnaire et attacher chaque variable possible à un mouvement oscillant simple.
L’étalon-or pour l’oscillation (mouvement régulier d’avant en arrière) est de prendre le sin() ou le cosinus() d’un minuteur. L’une ou l’autre opération retournera une valeur entre -1 et 1 pour TOUTE valeur passée, même si elle ne fait que compter. La seule différence entre les deux est qu’ils sont légèrement décalés - quand cos est 0, sin est -1 ou 1, et vice versa. Nous pouvons utiliser cela à notre avantage dans cette animation -
function update() {
// Find current time in milliseconds, then divide to slow down the animation speed let time = Date.now() / 100;
// Draw a background so the old shapes don't stick around ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath();
//USE ONE EXAMPLE AT A TIME // 1st example - side to side, y is constant ctx.arc(15 * Math.cos(time) + 160, 100, 30, 0, Math.PI * 2); // 2nd example - up and down, x is constant ctx.arc(160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2); // 3rd example - circle, x and y are variable ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2);
ctx.fillStyle = "black"; ctx.fill();
window.requestAnimationFrame(update); }De Côté à Côté
Section intitulée « De Côté à Côté »
De Haut en Bas
Section intitulée « De Haut en Bas »
Cercle Complet
Section intitulée « Cercle Complet »
Il nous reste quelques attributs supplémentaires à modifier au fil du temps - le rayon du cercle, le remplissage et le contour. Je vais laisser les angles d’arc tranquilles pour l’instant afin de garder la forme simple car le reste sera assez flashy.
function update() {
let time = Date.now() / 100;
ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath(); ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30 + 15 * Math.sin(time), 0, Math.PI * 2);
ctx.fillStyle = `hsl(${180 + 180 * Math.cos(time)}, 100%, 50%)`; ctx.fill();
ctx.strokeStyle = `hsl(${180 + 180 * Math.sin(time)}, 100%, 50%)`; ctx.stroke();
window.requestAnimationFrame(update); }
Chaque attribut de chaque forme que nous avons créée jusqu’à présent peut être modifié au fil du temps, et chaque animation que je crée est une combinaison des compétences ci-dessus. Pour plus de détails sur la création d’animations réutilisables et efficaces, consultez notre page Callbacks !