Web-based Virtual Reality Environments

20. Animations

Animations are created using the Animation component.

In early versions of A-Frame, the Animation component was an external component and you needed to include a <script>:

<script src="https://unpkg.com/aframe-animation-component/dist/aframe-animation-component.min.js"></script>

In the latest versions of A-Frame, the Animation is component is already included, so you should not add any script for the animation.

To add animation to a primitive, we simply add an animation attribute and configure it with the animation properties. (As we have seen, properties are name=value; pairs):

<a-box position="0 1.6 -2" animation="property: rotation; to: 0 360 180; dur: 5000; loop: 2">

Don't be confused with the fact that one of the properties we need to configure for the animation is called… property.

The main properties are:

Example 1200-animations-01 [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

Easings

Easings defined how the animation progresses through time: does it have a constant speed?, or does it start slow but gains speed as it progresses?

There are many types of easing functions. Example 1200-animations-02-easings shows only a few. The main categories of easings are:

The easesomething category uses speficic functions for the variation of speed (the example illustrates only the Quad function). The animation component documentation lists other possibilities for easing: https://aframe.io/docs/1.0.0/components/animation.html#easings

To set the easing function to use in an animation we specify the easing property:

<a-box scale="0.5 0.5 0.5" position="-3 0 -4" 
  animation="property: position; dur: 5000; easing: linear; to: 3 0 -4; loop: true"  >
</a-box>

Analyse the source code of the following example and watch it run. Although it is hard to see, the boxes actually all take the same amount of time to reach their final position – 5 seconds.

Example 1200-animations-02-easings [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

Go to the A-Frame page that documents the Animation component and try out different easing functions in example 1200-animations-02-easings

Chaining animations

We can give the impression of chained animations (i.e., sequential animations in different objects) by carefully setting the duration and delay of each animation. The delay property tells A-Frame how long it should wait before starting the animation. In example 1200-animations-03-chaining we have three animated boxes:

  1. The animation of box #1 starts immediately (no delay) and lasts for 1 second.

  2. The animation of box #2 starts with a delay of 1 second (so it starts when the animation of box #1 ends) and lasts for 1 second.

  3. The animation of box #3 starts with a delay of 2 seconds (so it starts when the animation of box #2 ends) and lasts for 1 seconds.

<a-box
        position="-1 1.6 -2"
        scale="0.5 0.5 0.5"
        color="#ff0000"
        animation="property: height; from: 1; to: 2; dur: 1000; delay: 0"
      >
</a-box>

<a-box
        id="sec"
        position="0 1.6 -2"
        scale="0.5 0.5 0.5"
        color="#00ff00"
        animation="property: height; from: 1; to: 2; dur: 1000; delay: 1000"
      >
</a-box>

<a-box
        id="thi"
        position="1 1.6 -2"
        scale="0.5 0.5 0.5"
        color="#0000ff"
        animation="property: height; from: 1; to: 2; dur: 1000; delay: 2000"
      >
</a-box>
Example 1200-animations-03-chaining [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

Rotation and scale axis

You have noticed that in previous animations, the boxes grow and rotate from their center. This is because the reference point for most entities in A-Frame is the center of the object. What if we want to rotate a box not around the center but from another arbitrary point?

For this we need to nest our object inside another entity and apply the animation to the outer entity. We then displace the inner object, displacing the reference point:

    <a-entity
        id="rotatingbox"
        position="0 2 -2"
        animation="property: rotation; from: 0 0 0; to: 0 0 360; dur: 1000; loop: true; easing: linear"
      >
        <a-box
          position="0 0.25 0"
          width="0.1"
          height="0.5"
          depth="0.1"
          color="#ff0000"
        >
        </a-box>
      </a-entity>

      <a-entity
        id="rotatingsphere"
        position="0 0 0"
        animation="property: rotation; from: 0 0 0; to: 0 360 0; dur: 5000; loop: true; easing: linear"
      >
        <a-sphere position="0 0 -5" radius="0.1" color="#00ff00"> </a-sphere>
      </a-entity>
Example 1200-animations-04-rotationaxis [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

We can do the same for scaling objects:

Example 1200-animations-05-scaleaxis [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

Animating multiple properties

We can animate multiple properties on the same entity by adding multiple Animation components to that entity. In order to do that, we need to change the name of the animation attribute because we cannot have the same attribute name duplicated in an HTML element. A-Frame does this by allowing us to append a suffix to the attribute name for the component. The suffic must come after a double underscore __ as in the following code:

<a-box
        position="-1 1.6 -2"
        scale="0.5 0.5 0.5"
        color="#ff0000"
        animation__height="property: height; from: 1; to: 2; dur: 1000; loop: 1"
        animation__rotation="property: rotation; from: 0 0 0; to: 360 0 0; dur: 1000; loop: true"
        animation__color="property: color; from: #ff0000; to: #0000ff; dur: 1000; loop: true; dir: alternate"
      >

Notice how we are addding 3 animations. Each animation is defined by the animation attribute with a different suffix __height, __rotation, and __color. I advice you to use suffix names that are meaningful – in my example, the suffix corresponds to the property that is being animated. This is not mandatory, though.

Also note that each animation is completely independent from the others. The __height animation only runs once (loop: 1). The __rotation and __color animations run forever (loop: true).

Also note that we can animate colors too! However, in order for colors to be animatable, you need to use the #rrggbb format.

Example 1200-animations-06-multiple [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

The __color animation in example 200-animations-04-multiple uses the dir property. Check the documentation for what it does…

Interactive animations

We can also make animations interactive by defining which events trigger an animation.

For example, if we want to start animating a box only when the cursor is over that box, we can define the startEvents property to mouseenter:

<a-box
        position="-1 1.6 -3"
        color="#ff0000"
        animation="property: height; dur: 2000; from: 1; to: 2; startEvents: mouseenter"
      >
</a-box>

Or to click even:

<a-box
        position="1 1.6 -3"
        color="#ffff00"
        animation="property: height; dur: 2000; from: 1; to: 2; startEvents: click"
      >
</a-box>
Example 1200-animations-07-events [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

We can even make the animation pause depending on interaction events by defining also the pauseEvents property:

      <a-box
        position="-1 1.6 -3"
        color="#ff0000"
        animation="property: height; dur: 2000; from: 1; to: 2; startEvents: click; pauseEvents: mouseleave"
      >
      </a-box>   

In the previous box, the animation starts when the box is clicked, and paused when the cursor leaves the box.

Example 1200-animations-08-eventspause [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

A-Frame Animations also has a resumeEvents property, but it does not seem to work correctly…

Example 1200-animations-09-events-proximity [new tab ] [source ]
Click to load.
Use keys 'w', 'a', 's', 'd' to move around.
Mouse to look around.

Exercises

Animations-01

Create an animation like in the following example. A series of six boxes stacked on each other. The bottom box is 5x5x0.25 meters, the next box 4x4x0.25 meters, 3x3x0.25, 2x2x0.25, 1x1x0.25, and the top box is 0.5x0.5x0.25. Boxes rotate indefinitely. The bottom box takes 5 seconds to complete one rotation and the next box takes 4 seconds, and so on…

Click to open in new tab

Animations-02

Try to recreate the animation in the following example. Note that the arm rotates around the shoulder point.

Click to open in new tab

References

Comments

Notice anything wrong? Have a doubt?


Copyright © 2022 Jorge C. S. Cardoso jorgecardoso@ieee.org