First Web Animation

What We'll Need

To run a Rive animation on web, we'll need three things: our Rive asset (a .riv file containing our animation), a canvas to draw on, and the Rive engine (rive.js).

Getting a Rive asset

To get a Rive asset (a .riv file), you can either create one using our tutorial or locate an existing one. For this tutorial, we'll use the following:

@riveSampleAssetUrl

Add a canvas

In your html file, let's add a canvas, where the animation will be drawn

<html>
<head>
    <title>Rive Sample 1</title>
</head>
<body>
    <canvas id="riveCanvas" width=512 height=512></canvas>
</body>
</html>

Getting and loading the Rive Engine (Rive.js)

Next, let's add the Rive engine. You can install rive using npm: rive-canvas or use a CDN as shown below.

<script src="https://unpkg.com/rive-canvas@0.0.10/rive.js"></script>
<script>
  ; (function () {
    // first, instantiate the Rive engine and load the WASM file(s)
    Rive({
      locateFile: (file) => 'https://unpkg.com/rive-canvas@0.0.10/' + file,
    }).then((rive) => {
        // Rive engine is ready
    });
  })();
</script>

* Two notes for javascript beginners - the semicolon in the beginning of the script protects our script from any unclosed script that may immediately precede ours. It's not needed in this particular case, but is a good habit. The (function() {...})(); construct is to create a function scope and execute it immediately.

See the source: sample code 1 (it's a blank page, view the source)

Opening an asset's artboard

With our Rive engine ready, let's load the asset and open the file's default artboard.

// Rive engine is ready
// Load up a Rive animation file, typically ending in '.riv'
const req = new Request('https://cdn.rive.app/animations/vapor_loader.riv');
  fetch(req).then((res) => {
    return res.arrayBuffer();
  }).then((buf) => {
    const file = rive.load(new Uint8Array(buf)); // the Rive engine loads a Rive asset via raw bytes

    const artboard = file.defaultArtboard();
  });
});

See the source: sample code 2 (it's still a blank page, view the source)

Draw a single frame

We've got the artboard, let's draw a single frame onto our canvas

// now we can access the animations; let's get one called 'vibration'
const vibrationAnim = artboard.animation('vibration');
const vibrationInstance = new rive.LinearAnimationInstance(vibrationAnim);
// let's grab our canvas
const canvas = document.getElementById('riveCanvas');
const ctx = canvas.getContext('2d');
// nw we can create a Rive renderer and wire it up to our 2D context
const renderer = new rive.CanvasRenderer(ctx);
// advance the artboard to render a frame
artboard.advance(0);
// Let's make sure our frame fits into our canvas
ctx.save();
renderer.align(rive.Fit.contain, rive.Alignment.center, {
    minX: 0,
    minY: 0,
    maxX: canvas.width,
    maxY: canvas.height
}, artboard.bounds);
// and now we can draw our frame to our canvas
artboard.draw(renderer);
ctx.restore();

See the source: sample code 3

Adding a loop

Now that we have successfully drawn a single frame, let's add a draw function with a loop, to continuously draw a loop of the animation. This code works by calling itself repeatedly.


// track the last time a frame was rendered
let lastTime = 0;

// okay, so we have an animation and a renderer; how do we play an animation?
// First, let's set up our animation loop with requestFrameAnimation
function draw(time) {
    // work out how many seconds have passed since a previous frame was drawn
    if (!lastTime) {
        lastTime = time;
    }
    const elapsedTime = (time - lastTime) / 1000;
    lastTime = time;

    // advance our animation by the elapsed time
    vibrationInstance.advance(elapsedTime);
    // apply the animation to the artboard
    vibrationInstance.apply(artboard, 1.0);
    // advance the artboard
    artboard.advance(elapsedTime);

    // render the animation frame
    // first, clear the canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    // let's resize it to fit the canvas
    ctx.save();
    renderer.align(rive.Fit.contain, rive.Alignment.center, {
        minX: 0,
        minY: 0,
        maxX: canvas.width,
        maxY: canvas.height
    }, artboard.bounds);
    // and now we can draw our frame to our canvas
    artboard.draw(renderer);
    ctx.restore();

    // and kick off the next frame
    requestAnimationFrame(draw);
}

// with the draw function ready, now we kick off the animation
requestAnimationFrame(draw);

See the source: sample code 4

Success!

This was a demonstration of how to run a simple looping animation on web using Rive. Next, we'll briefly discuss running animations on other platforms.