Although animating a button in Rive is easy, getting it to function as a clickable link in Webflow takes some custom code and specific structure within the state machine.

To make this work, the state machine needs to transition to a specific state on click so that the JS code can recognize when that state is entered and then redirect the page to the specified URL.

In the example above, there are four animation states.

  • Idle - the state the canvas waits in until a user interacts with it. The JS code sets the cursor to default when the animation is in this state.
  • Hover - Plays the hover animation while the user hovers over the button. The JS code sets the cursor to pointer when in this state so that users can tell it's clickable.
  • Click - Plays a brief animation when the user clicks
  • Linkout - a blank timeline that is transitioned to after the Click animation plays 100%

  1. Hover (Boolean) and Click (Trigger) inputs
  2. Listeners set up in the canvas to control the inputs.
  3. The state machine setup. Idle and Hover transition to each other on hover in and out. On click, the state machine progresses through Click to Linkout. When the state machine enters Linkout, the JS code tells the page to navigate to the specified URL.

Be sure to add the JS runtime script to the <head> tag either for the page you're on or for the whole project:
<script src="https://cdn.jsdelivr.net/npm/@rive-app/canvas@latest/rive.js"></script>
Copy Code
Here is the code that is used for the embedded example above: 
<canvas id="twitterbuttoncanvas-example" width="300" height="150" style="width: 300px; height: 150px;"></canvas>
<script>
let buttonCanvasExample = document.getElementById("twitterbuttoncanvas-example");
const twitterButtonExample = new rive.Rive({
  src:
    "https://ucarecdn.com/9bf156bd-7744-48e5-ba5f-e250f49ede21/tweeter_buttondemo.riv",
  canvas: document.getElementById("twitterbuttoncanvas-example"),
  autoplay: true,
  artboard: "Button",
  stateMachines: ["State Machine 1"],
  onLoad: () => {
    twitterButtonExample.resizeDrawingSurfaceToCanvas();
  },
  onStateChange: (riveEvent) => {
    const newStates = riveEvent.data;
    newStates.forEach((state) => {
      //name of the state transitioned to on click and the URL you want
      if (state.indexOf("Linkout") > -1) {
        window.location.href = "https://twitter.com/jeffamcavoy";
        //Add an else if for all states that should have the 'pointer' cursor
      } else if (state.indexOf("Hover") > -1) {
        buttonCanvasExample.style.cursor = "pointer";
      } else if (state.indexOf("Idle") > -1) {
        buttonCanvasExample.style.cursor = "default";
      }
    });
  }
});
</script> 
Copy Code
To see the process of setting up this button with the JS runtime check out this video