Accueil

Traduction

Tutoriel Canvas - sommaire

Tutoriel Canvas - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Canvas : animations basiques en POO

Le principe d'une animation Canvas est simple : appeler à intervalles réguliers une fonction d'animation via une instruction basée sur un 'timer' (setInterval() ou setTimeout()).

Écrire en objet le script d'animation

Il est fortement conseillé de recourir à la POO dans le cadre d'un canevas animé.
Le code sera alors beaucoup plus facile à comprendre car bien structuré.

Première animation

Le cercle a un rayon de plus en plus grand puis diminue et le cycle recommence.
Vous ne pouvez interrompre l'animation.

Le code correspondant

Le canevas 'responsive' est un repère cartésien de 300 par 300.

Le script

function fscript1()
{
	var canevas = document.querySelector('canvas'); 
	var ctx = canevas.getContext('2d');
	var X = canevas.width ; 
	var Y = canevas.height; 
	// définition d'un objet avec 4 propriétés et une méthode
	var rond = {x: X/2, y: Y/2, delta: 2,rayon: 20,dessin: function () 
	{
		ctx.beginPath();
		ctx.arc(this.x, this.y, this.rayon, 0, Math.PI * 2, true);
		ctx.fillStyle = "orange";
		ctx.fill();
	}, }; // fin définition objet rond
	
	setInterval(animate,100); 
	
	function animate()
	{
		ctx.clearRect(0,0, X,Y) ; 
		rond.dessin(); //appel méthode de l'objet
		rond.rayon += rond.delta;
		if (rond.rayon >= X/2)  {rond.delta = -rond.delta} ;
		if (rond.rayon <= 20) {rond.delta = -rond.delta};
	
	} // fin animate
} // fin fscript11
fscript1(); //appel fscript1

Ce script est "programmé objet".
Grâce à la syntaxe JSON, je crée un objet "rond" avec des propriété et une méthode : dessin().
Cette méthode dessin() est appelée dans la fonction animate().
La fonction animate() est appelée régulièrement (10 fois par seconde) avec l'instruction setInterval(animate,100)
Notez comment est géré l'alternace agrandissement puis réduction du rond : dès que le rayon maxi est atteint la propriété delta change de signe.

Animation 2

Le carré est de plus en plus grand et opaque puis de plus en plus petit et transparent ; le cycle recommence. Mais le carré doit toujours être centré dans la "toile".
Un clic dans le canevas provoque l'arrêt de l'animation.

Le code correspondant

Le canevas 'responsive' est un repère cartésien de 300 par 300?

Le script

function fscript2()
{
	var canevas = document.querySelectorAll('canvas')[1]; 
	var ctx = canevas.getContext('2d');
	var X = canevas.width ; 
	var Y = canevas.height; 
	var opacite = 0.02;
	var vo =0.005; // variation de l'opacité
	var carre = {x: X/2, y: Y/2, cote: 20, vc  : 2, dessin: function () 
		{
		ctx.fillRect(this.x, this.y, this.cote, this.cote); 
		ctx.fillStyle = "olive";
		}, 
	}; // fin définition objet carre
	
	var stop =setInterval(animate,100); 

	function animate()
    {
		ctx.clearRect(0, 0, X, Y); // effacement canevas
		ctx.globalAlpha = opacite ;
		carre.dessin() ; // appel méthode dessin
		carre.cote += carre.vc;
		if (carre.cote >= X) {carre.vc = -carre.vc ; vo = -vo;} ;
		if (carre.cote <= 20) {carre.vc = -carre.vc ;vo =-vo;} ;
		carre.x = (X-carre.cote)/2 ; 
		carre.y = (Y-carre.cote)/2 ; 
		opacite +=vo; 
		
	 } // fin animate
	canevas.onclick = function() {clearInterval(stop);}
} // fin script2

Le script est un peu plus compliqué car il faut calculer à chaque fois les nouvelles coordonnées de l'angle haut gauche du carré afin que ce carré soit toujours centré ; vc = variation du côté du carré.
De plus il faut faire varier l'opacité : vo = variation opacité.
Comme le script précédent j'ai recouru à la programmation objet avec création d'un objet nommé "carre".
Notez l'instruction qui met fin à l'animation : canevas.onclick = function() {clearInterval(stop);}. Il faut donc initialiser la variable stop : var stop =setInterval(animate,100);

Animation 3

Cette fois c'est le visiteur qui par clic successifs change l'aspect du rond qui devient de plus en plus grand et de plus en plus opaque.

L'animation

Le rond est d'abord très transparent puis à chaque clic dans le canevas il devient de plus en plus grand et de plus en plus opaque.

Le code correspondant

Ce troisième canevas est un repère cartésien de 300 par 300.

Le script

function fscript3()
{
	var canevas = document.querySelectorAll('canvas')[2]; 
	var contexte = canevas.getContext('2d');
	X = canevas.width;	
	Y = canevas.height;
	contexte.fillStyle	 ='purple'; 
	var opacite = 0.1;
	var rayon = 20; 
	var variation  = 5 ; 
	var rond = new Path2D();
	rond.arc(X/2,Y/2,rayon,0, 2 * Math.PI);
	contexte.globalAlpha = opacite;
	contexte.fill(rond); 
	
	canevas.onclick = function()
	{ 
		contexte.clearRect(0,0,X,Y);
		rayon += variation ; 
		if (rayon>= X/2) rayon = X/2;
		rond.arc(X/2,Y/2,rayon,0, 2 * Math.PI);
		contexte.fill(rond); 
		opacite = opacite + 0.05;
		contexte.globalAlpha = opacite;
	} // fin fonction anonyme
} // fin fscript3
fscript3(); 

J'utilise le constructeur d'objets Path2D pour définir une forme graphique (un rond) en début de script.

Animation 4

Ci-dessous un document HTML dans un Iframe.
Ce document comprend un canevas qui affiche une animation.

Les carrés sont bordurés de bleu et de plus en plus grand.

Le code correspondant

	var canevas = document.querySelector('canvas'); 
	var contexte = canevas.getContext('2d');
	X = canevas.width ;
	Y = canevas.height;
	var carre = new Path2D(); 
	carre.rect(0,0,X/6,X/6); 
	contexte.strokeStyle ="navy"; 
	contexte.lineWidth =3;
	var echelle =1.1;
	var stop;
	
	canevas.onclick = function() {stop = setInterval(animer,500);}
	canevas.onmouseout = function() {clearInterval(stop);}
	
	function animer()
	{
		contexte.stroke(carre) ; 
		contexte.scale(echelle,echelle);
	} // fin fonction animer

Un clic sur le canevas pour démarrer l'animation : canevas.onclick = function() {var stop =setInterval(animer,500);}
Pointeur en dehors du canevas pour arrêter l'animation : canevas.onmouseout = function() {clearInterval(stop);}
La fonction d'animation n'intègre pas l'instruction clearRect() puisque chaque nouveau carré doit s'ajouter aux anciens.