Animation

A-Frame propose un système d'animation assez complet allant des transitions de composants jusqu'à la simulation physique.

Transition

Tous les composants d'une entité (position, rotation, color, etc.) sont animables avec l'attribut animation. Une animation est définie avec les paramètres principaux suivants :

Paramètre Signification
property Nom du composant à animer
from Valeur du composant au début de l'animation
to Valeur du composant à la fin de l'animation
dur Durée de l'animation exprimée en millisecondes
loop Animation en boucle ?

Je vous invite à consulter la documentation pour découvrir l'intégralité des paramètres disponibles.

<a-scene>
  <a-sphere position="0 1.5 0" radius="0.5" color="#EF2D5E" shadow="cast: true; receive: true"
  animation="property: position; from: -5 1.5 0; to: 5 1.5 0; dur: 3000; easing: easeInOutQuad; dir: alternate; loop: true">
  </a-sphere>
        
  <a-plane id="plane" position="0 0 0" rotation="-90 0 0" width="12" height="12"
            color="#7BC8A4" shadow="cast: true; receive: true">
  </a-plane>
        
  <a-sky color="#CECECE"></a-sky>
        
  <a-entity light="type: ambient; color: white; intensity: 0.3"></a-entity>
  <!-- le spot est dirigé vers le centre du plan grâce à l'attribut target -->
  <a-entity light="type: spot; color: white; intensity: 0.7; angle: 30; penumbra: 0.25; castShadow: true; target: #plane" position="3 5 0">
  </a-entity>
          
  <a-camera position="0 2.6 6"></a-camera>
</a-scene>

Démo

Modèle 3D avec animation

Certains fichiers 3D peuvent contenir une ou plusieurs animations. Il existe une extension de A-Frame, appelée aframe-extras, qui permet de jouer l'animation attachée au modèle 3D. Pour ajouter cette extension à votre document Web, il suffit d'ajouter la ligne ci-dessous dans l'élément head du code source HTML.

<!-- A-Frame extras -->
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.2.0/dist/aframe-extras.min.js"></script>

L'attribut animation-mixer permet de choisir l'animation à jouer en passant le nom de celle-ci au paramètre clip. Dans l'exemple ci-dessous, le caractère * permet de jouer toutes les animations contenues dans le fichier beating-heart.glb.

Vous pouvez consulter la documentation dédiée aux Loaders de l'extension aframe-extras pour avoir plus de détails sur l'utilisation des animations embarquées dans un fichier 3D.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>VR Anatomy</title>
    <!-- A-Frame JavaScript library -->
    <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
    <!-- A-Frame extras -->
    <script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.2.0/dist/aframe-extras.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-assets>
        <a-asset-item id="heart" src="models/beating-heart.glb"></a-asset-item>
      </a-assets>

      <a-gltf-model src="#heart" position="0 -0.12 -0.25" animation-mixer="clip: *">
      </a-gltf-model>

      <a-sky color="#ECECEC"></a-sky>

      <a-camera position="0 0 0"></a-camera>
    </a-scene>
  </body>
</html>

Démo

L'extension aframe-extras prend aussi en charge d'autres formats 3D avec animation tel que le format FBX.

Conseil

Le portail mixamo d'Adobe regorge d'exemples de fichiers à télécharger.

<!doctype html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <title>FBX model + animation</title>
          <!-- A-Frame JavaScript library -->
          <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
          <!-- zlib JavaScript library for unzipping FBX files -->
          <script src="https://unpkg.com/zlibjs@0.3.1/bin/zlib.min.js"></script>
          <!-- A-Frame extras -->
          <script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.2.0/dist/aframe-extras.min.js"></script>
        </head>
        <body>
          <a-scene>
            <a-plane id="floor" rotation="-90 0 0" width="6" height="6" color="#7BC8A4"
            shadow="cast: false; receive: true"></a-plane>

            <a-entity id="dancer" fbx-model="src: url(rumba_dancing.fbx);" animation-mixer="clip: *; loop: pingpong"
            scale="0.01 0.01 0.01" rotation="0 0 0" shadow="cast: true; receive: false"></a-entity>
    
            <a-sky id="sphere" color="#A0A0A0"></a-sky>
    
            <a-entity light="type: ambient; color: white; intensity: 0.4"></a-entity>
            <a-entity light="type: spot; color: white; intensity: 0.8; angle: 20; penumbra: 0.35; target: #floor; castShadow: true" position="0 5 0"></a-entity>
    
            <a-camera position="0 1.7 4"></a-camera>
          </a-scene>
        </body>
      </html>

Démo

Dynamique

Le projet aframe-physics-system est un moteur physique pour A-Frame basé sur CANNON.js. Pour l'intégrer à votre scène, il suffit d'ajouter cette ligne dans l'entête de votre document HTML.

<!-- A-Frame physics system -->
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.2.2/dist/aframe-physics-system.min.js"></script>

Ce moteur physique permet d'attribuer des propriétés physiques (masse, contraintes, etc.) à des objets dynamiques (dynamic) qui interagissent entre eux ou avec des obstacles fixes ou animés (static). La liste exhaustive de toutes les propriétés physiques est disponible dans la documentation officielle.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>A-Frame: dynamics</title>
    <!-- A-Frame JavaScript library -->
    <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
    <!-- A-Frame physics system -->
    <script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.2.2/dist/aframe-physics-system.min.js"></script>
  </head>
  <body>
    <a-scene physics>
      <a-sphere position="0 0 -6" radius="0.3" color="#FFC65D"
      dynamic-body="shape: sphere; mass: 0.2; linearDamping: 0;">
      </a-sphere>
      
      <a-sphere position="0 1 -6" radius="0.3" color="#FFC65D"
      dynamic-body="shape: sphere; mass: 0.2; linearDamping: 0;">
      </a-sphere>
      
      <a-sphere position="-1 0 -6" radius="0.3" color="#FFC65D"
      dynamic-body="shape: sphere; mass: 0.2; linearDamping: 0;">
      </a-sphere>
      
      <a-sphere position="1 0 -6" radius="0.3" color="#FFC65D"
      dynamic-body="shape: sphere; mass: 0.2; linearDamping: 0;">
      </a-sphere>
      
      <a-sphere position="0 -1 -6" radius="0.3" color="#FFC65D"
      dynamic-body="shape: sphere; mass: 0.2; linearDamping: 0;">
      </a-sphere>

      <a-entity position="0 0 -6" animation="property: rotation; to: 0 0 360; loop: true; dur: 5000">
        <a-plane position="2 0 0" rotation="0 -90 0" width="4" height="4" color="#4CC3D9"
        static-body>
        </a-plane>

        <a-plane position="-2 0 0" rotation="0 90 0" width="4" height="4" color="#4CC3D9"
        static-body>
        </a-plane>

        <a-plane position="0 0 2" rotation="0 0 0" width="4" height="4" color="#4CC3D9" opacity="0.1"
        static-body>
        </a-plane>

        <a-plane position="0 0 -2" rotation="0 0 0" width="4" height="4" color="#4CC3D9"
        static-body>
        </a-plane>

        <a-plane position="0 2 0" rotation="90 0 0" width="4" height="4" color="#4CC3D9"
        static-body>
        </a-plane>

        <a-plane position="0 -2 0" rotation="-90 0 0" width="4" height="4" color="#4CC3D9"
        static-body>
        </a-plane>
      </a-entity>

      <a-sky color="#CCCCCC"></a-sky>
      <a-camera position="0 0 0"></a-camera>
    </a-scene>
  </body>
</html>

Démo