Faire tourner un objet sans tourner la boule
Article écrit par t-servi ( t-servi.com ).
Pour certaines applications, il est nécessaire de faire tourner des objets autour d'un centre. Le truc pour se simplifier la vie est de passer par un système de coordonées polaires. Cet article permet de voir comment on peut utiliser ce truc mathématique en javascript.
Coordonnées polaires
Le système de coordonnées polaires permet d'exprimer la position d'un objet en fonction d'un angle et d'un rayon. La formule ci-dessous permet de transformer des coordonnées polaires en coordonnées planaires :
x=x0+rayon*cos(angle) y=y0+rayon*sin(angle)
avec x0 et y0 la position du centre, rayon est la distance du centre à la position de l'objet et angle est l'angle entre le centre et l'objet.
Ci-dessous un lien vers un dessin explicite de wikipedia :
http://upload.wikimedia.org/wikipedia/comm...o_cartesian.svg
Préparation
Pour tester les capacités de ce système de coordonnées, il faut créer un fichier html et une image. Le fichier html est ci-dessous, il est composé de deux div. Une première div servira à afficher l'image, la seconde à afficher les variations de variables utilisées.
<html> <head> <title>Test</title> </head> <body> <div id="myImage1" style="position:absolute;left:100px;top:100px;">1 <img src="image.gif" height="30px"/> </div> <div id="monitoring" style="position:absolute;left:50px;top:400px;boder-width:1px;border-color:lightblue;border-style:solid;width:250px;background-color:#eeeeee;"> </div> </body> </html>
Vous pouvez voir le résult ici: http://www.t-servi.com/essais/javascript/roue/roue0.html
Ou encore télécharger le zip et ouvrir Test0.html
Positionner l'objet avec du javascript
Pour positionner l'objet, il suffit de donner une origine (noté x0 et y0), un rayon (noté radius) et un angle (noté angle). Ci-dessous la fonction javascript qui permet de transformer une coordonnée polaire en coordonnée planaire :
function position(objName,x0,y0,radius,angle) { obj=self.document.getElementById(objName); newX=x0+radius*Math.cos(angle); newY=y0-radius*Math.sin(angle); obj.style.left=newX; obj.style.top=newY; }
Voici le fichier html complet avec un appel de fonction qui positionne l'image en left=300 et top=200:
<html> <head> <title>Test</title> <script> function position(objName,x0,y0,radius,angle) { obj=self.document.getElementById(objName); newX=x0+radius*Math.cos(angle); newY=y0-radius*Math.sin(angle); obj.style.left=newX; obj.style.top=newY; } </script> </head> <body> <div id="myImage1" style="position:absolute;left:100px;top:100px;">1 <img src="image.gif" height="30px"/> </div> <div id="monitoring" style="position:absolute;left:50px;top:400px;boder-width:1px;border-color:lightblue;border-style:solid;width:250px;background-color:#eeeeee;"> </div> <script> position('myImage1', 200, 200, 100,0 ) </script> </body> </html>
Vous pouvez voir le résult ici: http://www.t-servi.com/essais/javascript/roue/roue1.html
Ou encore télécharger le zip et ouvrir Test1.html
Faire tourner l'objet avec du javascript
Pour l'instant l'objet est statique, mais il est possible de le faire bouger. Par exemple on aimerait que l'objet effectue un arc de cercle autour du centre. L'objet a donc une accélération angulaire nulle. La formule du mouvement est donc:
r(t)=v*t+r0
avec r(t) qui est la position en fonction du temps, v qui est la vitesse angulaire, t qui est le temps et r0 la position d'origine.
Voici ce que cette équation donne, appliquée à l'exemple:
<html> <head> <title>Test</title> <script> function position(objName,x0,y0,radius,angle) { obj=self.document.getElementById(objName); newX=x0+radius*Math.cos(angle); newY=y0-radius*Math.sin(angle); obj.style.left=newX; obj.style.top=newY; } function changePosition() { angle=temps*0.001; // vitesse angulaire est de 0.001 position('myImage1',400,200,100,angle); myDiv=document.getElementById('monitoring'); myDiv.innerHTML='Temps='+temps+'<br/>\n'+'Angle='+angle+'<br/>\n' temps+=intervalDeTemps; } </script> </head> <body> <div id="myImage1" style="position:absolute;left:100px;top:100px;">1 <img src="image.gif" height="30px"/> </div> <div id="monitoring" style="position:absolute;left:50px;top:400px;boder-width:1px;border-color:lightblue;border-style:solid;width:250px;background-color:#eeeeee;"> </div> <script> var intervalDeTemps=50; var temps=0; position('myImage1', 400, 200, 100,0 ) myInterval=setInterval("changePosition()",intervalDeTemps); </script> </body> </html>
Vous pouvez voir le résult ici: http://www.t-servi.com/essais/javascript/roue/roue2.html
Ou encore télécharger le zip et ouvrir Test2.html
Un mouvement exotique
Et si il fallait faire un mouvement plus exotique, du genre un mouvement qui accélère et décélère:
r(t)=k*sin(t)+r0
Voici ce mouvement particulier implémenté dans l'exemple:
<html> <head> <title>Test</title> <script> function position(objName,x0,y0,radius,angle) { obj=self.document.getElementById(objName); newX=x0+radius*Math.cos(angle); newY=y0-radius*Math.sin(angle); obj.style.left=newX; obj.style.top=newY; } function changePosition() { angle=Math.sin(temps)*3.00; position('myImage1',400,200,100,angle); myDiv=document.getElementById('monitoring'); myDiv.innerHTML='Temps='+temps+'<br/>\n'+'Angle='+angle+'<br/>\n' temps+=intervalDeTemps; } </script> </head> <body> <div id="myImage1" style="position:absolute;left:100px;top:100px;">1 <img src="image.gif" height="30px"/> </div> <div id="monitoring" style="position:absolute;left:50px;top:400px;boder-width:1px;border-color:lightblue;border-style:solid;width:250px;background-color:#eeeeee;"> </div> <script> var intervalDeTemps=50; var temps=0; position('myImage1', 400, 200, 100,0 ) myInterval=setInterval("changePosition()",intervalDeTemps); </script> </body> </html>
Vous pouvez voir le résult ici: http://www.t-servi.com/essais/javascript/roue/roue3.html
Ou encore télécharger le zip et ouvrir Test3.html
Et si ce mouvement était appliqué à plusieurs objets? Il suffit d'utiliser un déphasage, pour l'exemple :
<html> <head> <title>Test</title> <script> function position(objName,x0,y0,radius,angle) { obj=self.document.getElementById(objName); newX=x0+radius*Math.cos(angle); newY=y0-radius*Math.sin(angle); obj.style.left=newX; obj.style.top=newY; } function changePosition() { angle=Math.sin(temps)*3.14; position('myImage1',400,200,100,angle); position('myImage2',400,200,100,angle+1.57); // 0.73 =+/- PI/2 position('myImage3',400,200,100,angle+3.14); // 1.57 =+/- PI position('myImage4',400,200,100,angle+4.71); // 2.3 =+/- 3*PI/2 position('myImage1',400,200,100,angle); myDiv=document.getElementById('monitoring'); myDiv.innerHTML='Temps='+temps+'<br/>\n'+'Angle='+angle+'<br/>\n' temps+=intervalDeTemps; } </script> </head> <body> <div id="myImage1" style="position:absolute;left:100px;top:100px;">1 <img src="image.gif" height="30px"/> </div> <div id="myImage2" style="position:absolute;left:100px;top:100px;">2 <img src="image.gif" height="30px"/> </div> <div id="myImage3" style="position:absolute;left:100px;top:100px;">3 <img src="image.gif" height="30px"/> </div> <div id="myImage4" style="position:absolute;left:100px;top:100px;">4 <img src="image.gif" height="30px"/> </div> <div id="monitoring" style="position:absolute;left:50px;top:400px;boder-width:1px;border-color:lightblue;border-style:solid;width:250px;background-color:#eeeeee;"> </div> <script> var intervalDeTemps=50; var temps=0; position('myImage1', 400, 200, 100,0 ) myInterval=setInterval("changePosition()",intervalDeTemps); </script> </body> </html>
Vous pouvez voir le résult ici: http://www.t-servi.com/essais/javascript/roue/roue4.html
Ou encore télécharger le zip et ouvrir Test4.html
Conclusion
Bonne chance pour vos futures spirales, rosaces, ellipses ou autres. Merci de votre attention
Référence
Sources
