Skip to main content
11d ago

What CDN URL can I use for the canvas-advanced in script tags and ES module?

For the Web/JS runtime what CDN URL can I use for:

1. a script tag
2. an ES6 module import

for the canvas-advanced - preferably without WASM but I do not know if that is possible. When I tried https://unpkg.com/@rive-app/canvas-advanced@2.17.3/rive.wasm it gives an error about MIME type wasm.

When I use https://unpkg.com/@rive-app/canvas@2.17.3 in a script tag it works, but I need canvas-advanced. I also want to know the URL for the script tag and the URL for the ES6 module import - or I guess if you only know one, then that would be handy too ;-).

I do not want to use NPM.

Sorry if I have missed this somewhere in the guide. I have looked several times and have been asking somewhat related questions here and in different places for a week now.

Thanks.

10 replies
11d ago

I found this https://rive.app/community/doc/low-level-api-usage/doctAfBY6v3P ... but it is fairly complex.

What I am trying to do is input my own x and y for Rive Listeners. So when someone sets a Rive Listener to follow the mouse, I can use stateMachine.PointerMove({x,y}) to trigger the interaction as I am loading the Rive app into another canvas. The PointerMove() method and other Pointer methods apparently exist in a Unity runtime https://help.rive.app/game-runtimes/unity/listeners but I want it for the Web/JS runtime. Any advice would be helpful - thanks.

11d ago

Hi! I'm not sure to understand. You want to translate the x,y you have to the canvas? like if you have a geometry and translate those x,y in a canvas to another?

11d ago

What I mean, is this is suppose to happen by default in the JS Runtime. Do you have an specific example or file?

(edited) 11d ago

Thanks for the response,

Just a bit of background. We are bringing Rive into ZIM which is a JavaScript Canvas Framework at https://zimjs.com

We have successfully brought in an animation here https://zimjs.com/rive/animation.html

We have successfully interacted with stateMachine inputs here https://zimjs.com/rive/interaction.html

But when the app has a Listener set, as you pointed out, we need to tell that listener the x and y relative to the location of the rive displayed on our canvas. This example demonstrates: https://zimjs.com/rive/listener_question.html and has the question in the code on line 55. BTW resize the window until you see the original rive canvas (we would hide that) and you can interact to see the pointer effect.

11d ago

Hi! To answer some of your questions first

Here is example code to include canvas-advanced using a script tag:

<html>
  <head>
    <title>Rive Hello World</title>
  </head>
  <body>
    <canvas id="rive-canvas" width="500" height="500"></canvas>

    <script type="module">
      import RiveCanvas from "https://unpkg.com/@rive-app/canvas-advanced@2.20.0";

      async function main() {
        const rive = await RiveCanvas({
          // Loads Wasm bundle
          locateFile: (_) =>
            `https://unpkg.com/@rive-app/canvas-advanced@2.20.0/rive.wasm`,
        });
        const canvas = document.getElementById("rive-canvas");

        const renderer = rive.makeRenderer(canvas);
        const bytes = await (
          await fetch(
            new Request("https://cdn.rive.app/animations/vehicles.riv")
          )
        ).arrayBuffer();
        const file = await rive.load(new Uint8Array(bytes));
        const artboard = file.defaultArtboard();
        let animation = new rive.LinearAnimationInstance(
          artboard.animationByIndex(0),
          artboard
        );

        let lastTime = 0;

        function renderLoop(time) {
          if (!lastTime) {
            lastTime = time;
          }
          const elapsedTimeMs = time - lastTime;
          const elapsedTimeSec = elapsedTimeMs / 1000;
          lastTime = time;

          renderer.clear();
          if (artboard) {
            if (animation) {
              animation.advance(elapsedTimeSec);
              animation.apply(1);
            }
            artboard.advance(elapsedTimeSec);
            renderer.save();
            renderer.align(
              rive.Fit.contain,
              rive.Alignment.center,
              {
                minX: 0,
                minY: 0,
                maxX: canvas.width,
                maxY: canvas.height,
              },
              artboard.bounds
            );
            artboard.draw(renderer);
            renderer.restore();
          }
          rive.requestAnimationFrame(renderLoop);
        }
        rive.requestAnimationFrame(renderLoop);
      }

      main();
    </script>
  </body>
</html>
(edited) 11d ago

For a more advanced example with a state machine see here:

11d ago

Okay - great - will try that out and let you know.

(edited) 11d ago

Thank you. I got it working https://zimjs.com/rive/fromrive.html by adding a StateMachine reference, capturing mouse relative to the artboard.bounds and calling pointerMove() on the stateMachine. Also, added the blink animation.

Now we will try to integrating the example with ZIM. In general, we will be reading in any Rive App, as opposed to a known app.

1. Should we ever expect multiple StateMachines? I think I read that it will be one per app?

2. Will I have to loop through all the animations and advance them? Do I have to avoid animations that are paused?

3. Might there be more than one Artboard?

Thanks in advance.

10d ago

Here is the Rive app working in ZIM with a Listener https://zimjs.com/rive/listener.html tested with scaling, rotating, moving the Rive display in ZIM - all good. Will need to handle pointerDown() and pointerUp() - are there docs for these?

We have not fully integrated this example. In the interactive ZIM example using the basic runtime, we had extended Rive() which works for inputs and animation. Not quite sure for Listeners - we could mimic Rive() but handle all the wasm stuff if a listener is detected. Can we tell if a listener is present in a Rive app?

Would there be some way for Rive to expose the Listener data without wasm? Like provide built in inputs for the three pointer events.

Sorry for so many questions. Cheers.

(edited) 9d ago

I see the wasm file has artboardCount() and artboardByIndex() which will let me loop through them. Similarly, the artboard has animationCount() and animationByIndex() and the same for stateMachine - but there will be only one per artboard. Found the RiveCanvas hasListeners property but by the time I make a RiveCanvas, I am already in wasm. So maybe will just make two options, 1. an extended Rive() class for animation and inputs, and 2. a RiveListener() class that people can use for Rive apps with listeners that remakes all the wasm stuff.