Optimisation d'une animation dans canvas de html5
Bonjour, ayant plut�t l'habitude de r�aliser mes animations en actionscript, je cherchais � comparer les deux technologies d'un point de vue fluidit� et facilit� de conception.
Je me suis focalis� sur une animation simple de dessin avec translation et rotation. une roue en d�placement avec un rep�re qui tourne � l'int�rieur.
ci-joint mes deux tentatives de r�alisation en javascript/html5
une sans utilisation de translate() rotate() et l'autre avec...
ci-joint :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>Roue javascript</title>
<meta charset="UTF-8">
</head>
<body>
<canvas id="canvas" width="1024" height="600">
<p> votre navigateur ne supporte pas Canvas. Mettez-le à jour</p>
</canvas>
<script type="text/javascript">
var canvas = document.querySelector('#canvas');
var context = canvas.getContext('2d');
var theta = 0; //angle de rotation en radian
var oldtheta = 0;//angle de rotation correspondant à la frame précédente
var R = 100; //rayon de la roue
var retour = new Boolean(false);
var penw = 3;
var pi=Math.PI;
function draw()
{
context.save();
context.strokeStyle = "black";
context.lineWidth = penw;
context.clearRect(R * oldtheta-penw, 10-penw, 2 * R+2*penw, 2 * R+2*penw); //obturation (on efface l'image précédente à chaque fois en tenant compte du pen width)
//dessin du contour de la roue
context.beginPath();
context.arc(R * theta+R, R + 10, R, 0, 2*pi);
context.stroke();
//dessin des quatre rayons
for (var i = 0; i <= 3; i++)
{
context.beginPath();
context.moveTo(R * (1+theta), R + 10);
context.lineTo(R * (1+theta+ Math.cos(theta + i * pi/2)), 10 + R * (1 + Math.sin(theta + i * pi/2)));
context.stroke();
}
//dessin du sol
context.beginPath();
context.moveTo(0, 2 * R + 13);
context.lineTo(canvas.width, 2 * R + 10+penw);
context.stroke();
if ((R * theta > canvas.width - 2*R) || (theta < 0)) {
retour = !retour;
}
}
function render()
{
draw();
window.requestAnimationFrame(render);
oldtheta = theta;
if (retour) {
theta += Math.PI / 180;
} else {
theta -= Math.PI / 180;
}
}
render();
window.requestAnimFrame =
window.requestAnimationFrame || // La fonction standard
window.webkitRequestAnimationFrame || // Chrome et Safari.
window.mozRequestAnimationFrame || // Firefox.
window.ORequestAnimationFrame || // Opera.
window.msRequestAnimationFrame; // Internet Explorer.
</script>
</body>
</html> |
la seconde :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
<!DOCTYPE html>
<html>
<head>
<title>roue en javascript</title>
<meta charset="UTF-8">
</head>
<body>
<canvas id="canvas" width="1024" height="600">
<p> votre navigateur ne supporte pas Canvas. Mettez-le à jour</p>
</canvas>
<script type="text/javascript">
var canvas = document.querySelector('#canvas');
var context = canvas.getContext('2d');
var theta = 0; //angle de rotation en radian
var R = 100; //rayon de la roue
var retour = new Boolean(false);
var penw = 3;
function draw()
{
context.save();
//obturation (on efface la frame précédente=> peu efficace ici-ça plombe l'animation)
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(R * theta + R, R + 10);//déplacement de l'origine du canvas au centre de la roue
context.rotate(theta);//rotation des axes du canvas
context.strokeStyle = "black";
context.lineWidth = penw;
//dessin du contour de la roue
context.beginPath();
context.arc(0, 0, R, 0, 2 * Math.PI);
context.stroke();
//dessin des quatre rayons
for (var i = 0; i <= 3; i++)
{
context.beginPath();
context.moveTo(0, 0);
context.lineTo(R * Math.cos(i * Math.PI / 2), R * Math.sin(i * Math.PI / 2));
context.stroke();
}
context.restore();//retour de l'origine du contexte graphique sur (0,0) en supprimant la rotation
//dessin du sol
context.beginPath();
context.moveTo(0, 2 * R + 10 + penw);
context.lineTo(canvas.width, 2 * R + 10 + penw);
context.stroke();
//gestion de l'aller et retour
if ((R * theta >= canvas.width - 2 * R) || (theta < 0)) {
retour = !retour;
}
}
function render()
{
draw();
window.requestAnimationFrame(render);
if (retour) {
theta += Math.PI / 180;
} else {
theta -= Math.PI / 180;
}
}
render();
window.requestAnimFrame =
window.requestAnimationFrame || // La fonction standard
window.webkitRequestAnimationFrame || // Chrome et Safari.
window.mozRequestAnimationFrame || // Firefox.
window.ORequestAnimationFrame || // Opera.
window.msRequestAnimationFrame; // Internet Explorer.
</script>
</body>
</html> |
Ma question est : quelle est la meilleure m�thode � adopter... faut-il privil�gier la seconde m�thode (translate() rotate() du canvas) plut�t que la premi�re ?
Sachant qu'il faudrait que j'obture uniquement sur le dessin de la pr�c�dente frame dont le canvas a subi une rotation...
Des id�es d'optimisation puisque je d�bute presque dans ce langage et que je ne suis pas convaincu de l'int�r�t de migrer vers html5/javascript hormis les plantages de flashplayer et la d�saffection de flash par les distributeurs de pub.