Dans cet article, on voit comment créer des animations grâce à des opérations de découpe et d'applique.
Une animation grâce à des découpes
Dans cet exemple, on anime des carrés grâce aux méthodes scissor()
et clear()
. Ensuite, on crée à nouveau une boucle d'animation grâce aux timers. Cette fois-ci, la position du carré (la zone de découpe) est mise à jour à chaque frame (on a environ une frame rafraîchie toutes les 17 millisecondes, ce qui correspond environ à 60fps (frame per second ou frame par seconde).
En revanche, la couleur du carré (définie avec clearColor
) est uniquement mise à jour lorsqu'un nouveau carré est créé. On voit ici que WebGL est un automate. Pour chaque carré, on définit sa couleur une fois puis on met à jour sa position à chaque frame. L'état lié à la couleur reste tel quel jusqu'à ce qu'un nouveau carré soit créé.
"use strict" window.addEventListener("load", setupAnimation, false); // Voici les variables qui permettront de // manipuler le contexte WebGL, la couleur // et la position des carrés. var gl, color = getRandomColor(), position; function setupAnimation (evt) { window.removeEventListener(evt.type, setupAnimation, false); if (!(gl = getRenderingContext())) return; gl.enable(gl.SCISSOR_TEST); gl.clearColor(color[0], color[1], color[2], 1.0); // À la différence de la fenêtre du navigateur, // l'axe vertical de WebGL va dans le sens croissant // du bas vers le haut. Dans cette position, on indique // que la position initiale du carré est en haut à gauche // du contexte de dessin position = [0, gl.drawingBufferHeight]; var button = document.querySelector("button"); var timer; function startAnimation(evt) { button.removeEventListener(evt.type, startAnimation, false); button.addEventListener("click", stopAnimation, false); document.querySelector("strong").innerHTML = "arrêter"; timer = setInterval(drawAnimation, 17); drawAnimation(); } function stopAnimation(evt) { button.removeEventListener(evt.type, stopAnimation, false); button.addEventListener("click", startAnimation, false); document.querySelector("strong").innerHTML = "lancer"; clearInterval(timer); } stopAnimation({type: "click"}); } // Les variables qui permettront de stocker la taille // et la vitesse du carré. var size = [60, 60], velocity = 3.0; function drawAnimation () { gl.scissor(position[0], position[1], size[0] , size[1]); gl.clear(gl.COLOR_BUFFER_BIT); // À chaque frame, on définit une position plus basse // pour le carré, c'est cela qui crée une illusion // de mouvement. position[1] -= velocity; // Lorsque le carré atteint le bas, on crée un nouveau // carré avec une nouvelle vitesse et une nouvelle // couleur. if (position[1] < 0) { // La position horizontale est choisie aléatoirement. // La position verticale correspond au haut // du buffer de dessin. position = [ Math.random()*(gl.drawingBufferWidth - size[0]), gl.drawingBufferHeight ]; // Ici on détermine une vitesse aléatoire // comprise entre 1.0 et 7.0 velocity = 1.0 + 6.0*Math.random(); color = getRandomColor(); gl.clearColor(color[0], color[1], color[2], 1.0); } } function getRandomColor() { return [Math.random(), Math.random(), Math.random()]; }
Le code source de cet exemple est également disponible sur GitHub.