Un exemple

Le document ci-dessous contient un rectangle vert et un rectangle rouge, chacun ayant subi une transformation géométrique différente. Un chemin les relie. Notez que ses extrémités ne sont pas situées rigoureusement aux centres des rectangles.

Voici un extrait du code source de ce document :

<svg xmlns="http://www.w3.org/2000/svg">
   <g id="conteneur">
      <rect id="depart" x="5" y="5" width="50" height="30"
              stroke="green" fill="#ada" fill-opacity="0.5"
              transform="translate(35, 50) scale(2) rotate(30)" />
      <rect id="arrivee" x="5" y="5" width="50" height="30"
              stroke="red" fill="#daa" fill-opacity="0.5"
              transform="translate(200, 250) scale(3) rotate(-30)" />
      <path id="chemin" d="M70,130 t50,50 t75,-75 t37,50 T330,260"
               stroke="#a80" fill="none" />
   </g>
</svg>

Nous souhaitons ajuster la caméra sur le rectangle vert (depart), puis animer son déplacement jusqu'au rectangle rouge (arrivee) en suivant le chemin.

Cliquez dans l'image pour observer le résultat.

La technique d'animation

Nous avons déjà détaillé les calculs géométriques nécessaires à l'animation de la caméra en ligne droite. Le lecteur retrouvera les explications dans les billets Ajuster l'affichage d'un document SVG sur une région délimitée par un rectangle, Animer une transformation SVG et Correction de trajectoire.

Ici, nous réutilisons toutes ces techniques. La nouveauté réside dans le fait qu'à chaque pas d'animation, les coordonnées de la caméra ne sont plus calculées par interpolation linéaire, mais en déterminant le point courant le long du chemin à parcourir.

Propriétés des rectangles et du chemin

L'accès aux propriétés géométriques des rectangles se fait à l'aide de la fonction calculerGeometrie donnée dans le billet Correction de trajectoire.

var depart = calculerGeometrie("depart");
var arrivee = calculerGeometrie("arrivee");

Nous introduisons la fonction suivante, dont le rôle est de fournir des informations sur un chemin :

  • sa longueur,
  • les coordonnées de son point de départ et de son point d'arrivée,
  • les facteurs d'échelle à appliquer le long des axes horizontal et vertical pour ajuster le chemin aux centres des rectangle d'origine et de destination.
function calculerDonneesChemin (id, origine, destination) {
   var result = {
      path: document.getElementById("chemin")
   };
 
   result.length = result.path.getTotalLength();
 
   var startPoint = result.path.getPointAtLength(0);
   var endPoint = result.path.getPointAtLength(result.length);
 
   result.startX = startPoint.x;
   result.startY = startPoint.y;
   result.scaleX = (destination.cx - origine.cx) / ((endPoint.x - startPoint.x) || 1);
   result.scaleY = (destination.cy - origine.cy) / ((endPoint.y - startPoint.y) || 1);
   return result;
}
 
var chemin = calculerDonneesChemin("chemin", depart, arrivee);

Si les extrémités du chemin sont disposées horizontalement ou verticalement, il faut que les centres des rectangles soient disposés de la même manière, sinon les attributs scaleX et scaleY n'ont aucun sens.

Interpolation

Dans la fonction avancer, le calcul de l'interpolation est modifié de la manière suivante :

// Interpolation linéaire de tous les attributs
var inter = {};
for (var attr in depart) {
   inter[attr] = depart[attr] * restant + arrivee[attr] * progression;
}
 
// Interpoler les coordonnées du centre en suivant le chemin
var point = chemin.path.getPointAtLength(chemin.length * progression);
inter.cx = depart.cx + chemin.scaleX * (point.x - chemin.startX);
inter.cy = depart.cy + chemin.scaleY * (point.y - chemin.startY);

Nous retrouvons l'utilisation de la méthode getPointAtLength utilisée dans le billet Suivre un chemin dans un document SVG.

En observant le résultat de l'animation, nous constatons que le trajet effectivement suivi par la caméra n'est pas rigoureusement superposé avec le chemin. Ceci est dû au fait que, dans le calcul d'interpolation, nous appliquons une transformation aux points du chemin afin que ses extrémités coïncident avec les centres des rectangles.

Téléchargement