diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index ae85809..406b5b3 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -23,13 +23,3 @@ jobs:
run: npm test
- name: Build
run: npm run build
- - name: Git config
- run: |
- git config --local user.email 'hello@rive.app'
- git config --local user.name ${{ github.actor }}
- - name: Authenticate with registry
- run: npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }}
- - name: Release
- env:
- GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
- run: npm run release
diff --git a/README.md b/README.md
index a838879..a33a819 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,30 @@ npm i --save rive-react
_Note: This library is using React hooks so the minimum version required for both react and react-dom is 16.8.0._
+### Migrating from v 0.0.x to 1.x.x
+
+Starting in v 1.0.0, we've migrated from wrapping around the `@rive-app/canvas` runtime (which uses the `CanvasRendereringContext2D` renderer) to the `@rive-app/webgl` runtime (which uses the WebGL renderer). The high-level API doesn't require any change to upgrade, but there are some notes to consider about the backing renderer.
+
+The backing `WebGL` runtime allows for best performance across all devices, as well as support for some features that are not supported in the `canvas` renderer runtime. To allow the `react` runtime to support some of the newer features in Rive, we needed to switch the `rive-react` backing runtime to `@rive-app/webgl`.
+
+One note about this switch is that some browsers may limit the number of concurrent WebGL contexts. For example, Chrome may only support up to 16 contexts concurrently. We pass a property called `useOffscreenRenderer` set to true to the backing runtime when instantiating Rive by default, which helps to manage the lifecycle of the `canvas` with a single offscreen `WebGL` context, even if there are many Rive animations on the screen (i.e 16+). If you need a single `WebGL` context per Rive animation/instance, pass in the `useOffscreenRenderer` property set to `false` in the `useRive` options, or as a prop in the default export component from this runtime. See below for an example:
+
+```js
+const {rive, RiveComponent} = useRive({
+ src: 'foo.riv',
+}, {
+ // Default (you don't need to set this)
+ useOffscreenRenderer: true,
+ // To override and use one context per Rive instance, uncomment and use the line below
+ // useOffscreenRenderer: false,
+});
+
+// or you can override the flag in JSX via props
+return (
+
+);
+```
+
## Usage
### Component
@@ -106,6 +130,7 @@ export default Example;
- `useDevicePixelRatio`: _(optional)_ If `true`, the hook will scale the resolution of the animation based the [devicePixelRatio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio). Defaults to `true`. NOTE: Requires the `setContainerRef` ref callback to be passed to a element wrapping a canvas element. If you use the `RiveComponent`, then this will happen automatically.
- `fitCanvasToArtboardHeight`: _(optional)_ If `true`, then the canvas will resize based on the height of the artboard. Defaults to `false`.
+- `useOffscreenRenderer`: _(optional)_ If `true`, the Rive instance will share (or create if one does not exist) an offscreen `WebGL` context. This allows you to display multiple Rive animations on one screen to work around some browser limitations regarding multiple concurrent WebGL contexts. If `false`, each Rive instance will have its own dedicated `WebGL` context, and you may need to be cautious of the browser limitations just mentioned. Defaults to `true`.
### useStateMachineInput Hook
diff --git a/package.json b/package.json
index f955c38..82d4ce3 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
},
"homepage": "https://github.com/rive-app/rive-react#readme",
"dependencies": {
- "@rive-app/canvas": "1.0.18"
+ "@rive-app/webgl": "1.0.25"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
diff --git a/setupTests.ts b/setupTests.ts
index 638a0d4..aecc97b 100644
--- a/setupTests.ts
+++ b/setupTests.ts
@@ -24,7 +24,7 @@ window.IntersectionObserver = class IntersectionObserver {
unobserve() {}
};
-jest.mock('@rive-app/canvas', () => ({
+jest.mock('@rive-app/webgl', () => ({
Rive: jest.fn().mockImplementation(() => ({
on: jest.fn(),
stop: jest.fn(),
diff --git a/src/components/Rive.tsx b/src/components/Rive.tsx
index 38637b0..bf0065b 100644
--- a/src/components/Rive.tsx
+++ b/src/components/Rive.tsx
@@ -1,4 +1,4 @@
-import { Layout } from '@rive-app/canvas';
+import { Layout } from '@rive-app/webgl';
import React, { ComponentProps } from 'react';
import useRive from '../hooks/useRive';
@@ -7,6 +7,7 @@ export type RiveProps = {
artboard?: string;
animations?: string | string[];
layout?: Layout;
+ useOffscreenRenderer?: boolean;
};
const Rive = ({
@@ -14,6 +15,7 @@ const Rive = ({
artboard,
animations,
layout,
+ useOffscreenRenderer = true,
...rest
}: RiveProps & ComponentProps<'div'>) => {
const params = {
@@ -24,7 +26,11 @@ const Rive = ({
autoplay: true,
};
- const { RiveComponent } = useRive(params);
+ const options = {
+ useOffscreenRenderer,
+ };
+
+ const { RiveComponent } = useRive(params, options);
return ;
};
diff --git a/src/hooks/useRive.tsx b/src/hooks/useRive.tsx
index c38d136..264e719 100644
--- a/src/hooks/useRive.tsx
+++ b/src/hooks/useRive.tsx
@@ -6,7 +6,7 @@ import React, {
ComponentProps,
RefCallback,
} from 'react';
-import { Rive, EventType } from '@rive-app/canvas';
+import { Rive, EventType } from '@rive-app/webgl';
import {
UseRiveParameters,
UseRiveOptions,
@@ -44,6 +44,7 @@ function RiveComponent({
const defaultOptions = {
useDevicePixelRatio: true,
fitCanvasToArtboardHeight: false,
+ useOffscreenRenderer: true,
};
/**
@@ -164,7 +165,12 @@ export default function useRive(
const setCanvasRef: RefCallback = useCallback(
(canvas: HTMLCanvasElement | null) => {
if (canvas && riveParams) {
- const r = new Rive({ ...riveParams, canvas });
+ const {useOffscreenRenderer} = options;
+ const r = new Rive({
+ useOffscreenRenderer,
+ ...riveParams,
+ canvas,
+ });
r.on(EventType.Load, () => setRive(r));
} else if (canvas === null && canvasRef.current) {
canvasRef.current.height = 0;
diff --git a/src/hooks/useStateMachineInput.ts b/src/hooks/useStateMachineInput.ts
index b6212ea..97dfab1 100644
--- a/src/hooks/useStateMachineInput.ts
+++ b/src/hooks/useStateMachineInput.ts
@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react';
-import { Rive, StateMachineInput } from '@rive-app/canvas';
+import { Rive, StateMachineInput } from '@rive-app/webgl';
/**
* Custom hook for fetching a stateMachine input from a rive file.
diff --git a/src/index.ts b/src/index.ts
index 28b2951..9f36ca0 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,4 +5,4 @@ import useStateMachineInput from './hooks/useStateMachineInput';
export default Rive;
export { useRive, useStateMachineInput };
export { RiveState, UseRiveParameters, UseRiveOptions } from './types';
-export * from '@rive-app/canvas';
+export * from '@rive-app/webgl';
diff --git a/src/types.ts b/src/types.ts
index 0290776..931e0af 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,11 +1,12 @@
import { RefCallback, ComponentProps } from 'react';
-import { Rive, RiveParameters } from '@rive-app/canvas';
+import { Rive, RiveParameters } from '@rive-app/webgl';
export type UseRiveParameters = Partial> | null;
export type UseRiveOptions = {
useDevicePixelRatio: boolean;
fitCanvasToArtboardHeight: boolean;
+ useOffscreenRenderer: boolean;
};
export type Dimensions = {
diff --git a/test/useRive.test.tsx b/test/useRive.test.tsx
index a6ccace..9ce12c0 100644
--- a/test/useRive.test.tsx
+++ b/test/useRive.test.tsx
@@ -2,9 +2,9 @@ import { renderHook, act } from '@testing-library/react-hooks';
import { mocked } from 'jest-mock';
import useRive from '../src/hooks/useRive';
-import * as rive from '@rive-app/canvas';
+import * as rive from '@rive-app/webgl';
-jest.mock('@rive-app/canvas', () => ({
+jest.mock('@rive-app/webgl', () => ({
Rive: jest.fn().mockImplementation(() => ({
on: jest.fn(),
stop: jest.fn(),