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

Trois superbes animations Canvas

Un diaporama automatique

Ci-dessous un document HTML contenant un canevas qui tient lieu de diaporama.

Toutes les deux secondes affichage d'une nouvelle photo sexy.
Remarquez que les photos sont toujours bien centrées dans le canevas et qu'elles ne sont jamais déforméés.
Par aillleurs elles apparaissent avec deux filtres : effet sépia et ombrage.

Cliquez sur le bouton de commmande pour mettre fin au diaporama.
Actualisez la page pour relancer l'animation.

Le code HTML

Le script

Il n'est pas très compliqué.

var routine; 
function f1()
{
	var canevas = document.querySelector('canvas'); 
	var contexte = canevas.getContext('2d');
	contexte.filter ="sepia(1) drop-shadow(10px 10px 3px gray)"; 
	var X =canevas.width;
	var Y =canevas.height;

	function ajout()
	{
		contexte.clearRect(0,0,X,Y); 
		var image = new Image(); 
		var reel = Math.random() ;
		var entier = Math.ceil(reel*25) ; 
		switch(entier)
		{
			case 1 : image.src ="../images/japonaise_nue.jpg" ; break;
			case 2 : image.src ="../images/black_nue.jpg" ; break;
			...
			case 25 : image.src ="../images/bikini28.jpg" ; break;
			} // fin switch 
		image.onload =function()
		{
			largeur =image.width; 
			hauteur =image.height; 
			ratio = hauteur /largeur; 
			largeur_fixee = X/100*60; 
			hauteur_fixee = largeur_fixee * ratio; 
			var x = (X-largeur_fixee)/2;
			var y = (Y-hauteur_fixee)/2;
			contexte.drawImage(image,x,y,largeur_fixee,hauteur_fixee) ;
		} // fin fonction anonyme
	} // fin fonction ajout
	routine = setInterval(ajout,2000);
} // fin f1
f1();  // appel f1

La variable entier contient un entier comprend un entier compris entre 1 et 25 et généré de façon aléatoire.
On récupère dans les variables largeur & hauteur les dimensions de l'image chargée. A partir de ces infos on calcule les dimensions d'affichage de l'image et la position de son coin supérieur gauche afin qu'elle soit toujours centrée dans le canevas et jamais déformée.

Une image reste affichée deux secondes (2000 millisecondes) avant qu'elle ne soit effacée puis remplacée par une nouvelle.
routine doit être une variable globale (donc déclarée en dehors de toute procédure) afin que l'instruction clearInterval(routine) fonctionne.

Une horloge qui donne l'heure exacte

Ci-dessous un document HTML contenant un canevas qui affiche une horloge.

Je tiens à préciser que je ne suis pas l'auteur de cette animation. Je l'ai trouvée sur le tutoriel Canvas de la fondation Mozilla.
Suivez le lien

Le code

HTML : <canvas id ="canevas" width = '150' height = '150' style ="width : 60%; height : auto;" > ...

Le script :

Je me suis contenté de franciser les noms des variables.

function clock()
{
  var maintenant = new Date();
  var ctx = document.getElementById('canevas').getContext('2d');
  ctx.save();
  ctx.clearRect(0,0,150,150);
  ctx.translate(75,75);
  ctx.scale(0.4,0.4);
  ctx.rotate(-Math.PI/2);
  ctx.strokeStyle = "black";
  ctx.fillStyle = "white";
  ctx.lineWidth = 8;
  ctx.lineCap = "round";

  // Marquage des heures
  ctx.save();
  for (var i=0;i<12;i++)
  {
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.moveTo(100,0);
    ctx.lineTo(120,0);
    ctx.stroke();
  }
  ctx.restore();

  // Marquage des minutes
  ctx.save();
  ctx.lineWidth = 5;
  for (i=0;i<60;i++)
  {
    if (i%5!=0) 
	{
      ctx.beginPath();
      ctx.moveTo(117,0);
      ctx.lineTo(120,0);
      ctx.stroke();
    }
    ctx.rotate(Math.PI/30);
  }
  ctx.restore();

  var sec = maintenant.getSeconds();
  var min = maintenant.getMinutes();
  var hr  = maintenant.getHours();
  hr = hr>=12 ? hr-12 : hr;

  ctx.fillStyle = "black";

  // Aiguille des heures
  ctx.save();
  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
  ctx.lineWidth = 14;
  ctx.beginPath();
  ctx.moveTo(-20,0);
  ctx.lineTo(80,0);
  ctx.stroke();
  ctx.restore();

  // Aiguille des minutes
  ctx.save();
  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(-28,0);
  ctx.lineTo(112,0);
  ctx.stroke();
  ctx.restore();

  // Aiguille des secondes
  ctx.save();
  ctx.rotate(sec * Math.PI/30);
  ctx.strokeStyle = "#D40000";
  ctx.fillStyle = "#D40000";
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(-30,0);
  ctx.lineTo(83,0);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(95,0,10,0,Math.PI*2,true);
  ctx.stroke();
  ctx.fillStyle = "rgba(0,0,0,0)";
  ctx.arc(0,0,3,0,Math.PI*2,true);
  ctx.fill();
  ctx.restore();

  ctx.beginPath();
  ctx.lineWidth = 14;
  ctx.strokeStyle = '#325FA2';
  ctx.arc(0,0,142,0,Math.PI*2,true);
  ctx.stroke();

  ctx.restore();

  window.requestAnimationFrame(clock);
} // fin fonction clock
window.requestAnimationFrame(clock);

Notez l'emploi d'une nouvelle méthode window.requestAnimationFrame(fonction) pour animer le canvas.
Cette méthode rend les animations beaucoup plus fluides qu'avec un 'timer' (méthode setInterval).
Ici la fonction clock() est exécutée 60 fois par seconde. Ce qui est parfait puisqu'une minute comprend 60 secondes.

Un jeu de squash

Intérêt de ce jeu : programmation du clavier.
Ci-dessous un document HTML qui affiche le jeu de squash.

Utilisez les flèches droite et gauche du clavier pour déplacer la raquette.

Le code

Code HTML :

Le script

var canvas = document.querySelector("canvas");
var contexte = canvas.getContext("2d");
var X = canvas.width;         
var Y = canvas.height;  
var balleDX = 2 ; var  balleDY = 4 ;  
// vitesse initiale de déplacement de la balle
// déclaration de variables globales
var balleX, balleY; // position initiale de la balle
var raquetteX; // position initiale X de la raquette
var raquetteH ;// hauteur raquette
var raquetteW;  // largeur de la raquette
var raquetteD;  // position initiale Y de la raquette
	
init(); 	// appel fonction initialisation
	
// dessiner balle et raquette à leur position initiale 
raquette();	// appel fonction 
balle() ; 	// appel fonction
	
document.querySelector('button').onclick = function()
{
	var stop = setInterval(jeuballe, 30); 
		// appel de la fonction jeuballe tous les 30 millisecondes
	document.onkeydown = function(e)
	{	// si appui sur une touche
		if ((e.keyCode == 37) || (e.keycode == 81)) gauche(); 	
		if ((e.keyCode == 39) || (e.keycode == 83)) droite(); 		
	} // fin fonction 

function jeuballe()
{
  contexte.clearRect(0, 0, X, Y);           // effacer la zone de dessin
	raquette(); //dessiner raquette à sa nouvelle position 
	balle(); // dessiner balle à sa nouvelle position
        
    // changer coordonnées ballee
    balleX += balleDX;            
	balleY += balleDY;
    // si balle touche bords droit ou gauche 
    if (balleX + balleDX > X - 15 || balleX + balleDX < 15) balleDX = -balleDX;

    // si balle touche le bord haut
    if (balleY + balleDY < 15) balleDY = -balleDY;
    // si balle touche le bord bas
    else if (balleY + balleDY > Y - 15) 
	{
                // et si balle touche la raquette
		if (balleX > raquetteX && balleX < raquetteX + raquetteW) balleDY = -balleDY;
                // Sinon : perdu !
	else 
	{
		clearInterval(stop);
        alert("Perdu!");
		init() ;
    }
       } // fin sinon
} // fin fonction jeuballe
} // fin fonction anonyme appelée sur clic du bouton de commande
	
function gauche()
{    
	raquetteX = raquetteX - 20;   
	if (raquetteX < 0) raquetteX = 0;}
function droite()
{ 
	raquetteX = raquetteX + 20;  
	if (raquetteX > X - raquetteW) raquetteX = X - raquetteW;
}
function raquette() 
{
	// Dessiner la raquette
    contexte.fillStyle = "navy";
    contexte.beginPath();  
	contexte.rect(raquetteX, raquetteD, raquetteW, raquetteH);
    contexte.closePath();           
	contexte.fill();
}
function balle()
{
	// Dessiner la balle
    contexte.fillStyle = "red";
    contexte.beginPath();       
	contexte.arc(balleX, balleY, 15, 0, Math.PI * 2, true);
    contexte.closePath();       
	contexte.fill();
}
	
function init()
{	
	// valeurs initiales variables 
	balleX = 150;         balleY = 50; 
	raquetteX = 150; 
	raquetteH = 10; 
	raquetteW = 100; 
	raquetteD = 390 ; 
   }

Le code est décomposé en deux nombreuses fonctions : structure qui facilite la compréhension relativement rapide de ce code.
Sur quelle instruction jouer pour ralentir ou accéler le jeu ???
Réponse : var stop = setInterval(jeuballe, 30);
Vous pouvez aussi modifier les valeurs des variables "balleDX" & "balleDY"

La programmation du clavier

L'un des intérêts de cette application est la programmation du clavier.

document.onkeydown = function(e)
{	// si appui sur une touche
	if ((e.keyCode == 37) || (e.keycode == 81)) gauche(); 	// déplacement à gauche raquette
	if ((e.keyCode == 39) || (e.keycode == 83)) droite(); 	
}