mirror of
https://github.com/rive-app/rive-react.git
synced 2026-03-13 08:22:30 +08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2153b81e6b | ||
|
|
6b1500e681 | ||
|
|
503702cf1f | ||
|
|
7be20b0a87 | ||
|
|
78491f5819 | ||
|
|
39edb88a19 | ||
|
|
fd1a1653b1 | ||
|
|
8d7f0ab28c | ||
|
|
2a2e532564 | ||
|
|
2b1aa01a87 | ||
|
|
06c4e2aea3 | ||
|
|
819bd51ea9 |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -4,9 +4,45 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v3.0.30](https://github.com/rive-app/rive-react/compare/v3.0.28...v3.0.30)
|
||||
|
||||
- Bump dependencies to fix call to runtime cleanup [`6b1500e`](https://github.com/rive-app/rive-react/commit/6b1500e681ba8984d786eec4d414c4c8ad4b0268)
|
||||
|
||||
#### [v3.0.28](https://github.com/rive-app/rive-react/compare/v3.0.27...v3.0.28)
|
||||
|
||||
> 20 October 2022
|
||||
|
||||
- chore: release 3.0.28 [`78491f5`](https://github.com/rive-app/rive-react/commit/78491f5819b78b2e7435a2509e89fd3c672f3126)
|
||||
- Bump canvas and webgl dependencies to fix alignment memory leaks [`39edb88`](https://github.com/rive-app/rive-react/commit/39edb88a19aaff478e4e9cbeeef58414f28fdb60)
|
||||
|
||||
#### [v3.0.27](https://github.com/rive-app/rive-react/compare/v3.0.26...v3.0.27)
|
||||
|
||||
> 4 October 2022
|
||||
|
||||
- chore: release 3.0.27 [`fd1a165`](https://github.com/rive-app/rive-react/commit/fd1a1653b13c2fd15f2862e6c372a27fd49acd00)
|
||||
- Fix: Bump wasm to accomodate clipping bug on nested artboards [`8d7f0ab`](https://github.com/rive-app/rive-react/commit/8d7f0ab28c8aa6af3abe5269e7b8980cc1a8dbe7)
|
||||
|
||||
#### [v3.0.26](https://github.com/rive-app/rive-react/compare/v3.0.25...v3.0.26)
|
||||
|
||||
> 22 September 2022
|
||||
|
||||
- fix: Adjust canvas size if devicePixelRatio changes for any reaason [`2b1aa01`](https://github.com/rive-app/rive-react/commit/2b1aa01a87c14f71b980d160f6607edc12d3eed6)
|
||||
- chore: release 3.0.26 [`2a2e532`](https://github.com/rive-app/rive-react/commit/2a2e53256401b6d7137db4b73c5901d587a888af)
|
||||
|
||||
#### [v3.0.25](https://github.com/rive-app/rive-react/compare/v3.0.24...v3.0.25)
|
||||
|
||||
> 21 September 2022
|
||||
|
||||
- chore: release 3.0.25 [`06c4e2a`](https://github.com/rive-app/rive-react/commit/06c4e2aea39d8e08ee12760663bd612ca77f3e9c)
|
||||
- patch: bump js runtime dependency to address content security policy issue in WASM build [`819bd51`](https://github.com/rive-app/rive-react/commit/819bd51ea976bbea0c218379cd88304bd1738323)
|
||||
|
||||
#### [v3.0.24](https://github.com/rive-app/rive-react/compare/v3.0.23...v3.0.24)
|
||||
|
||||
> 15 September 2022
|
||||
|
||||
- add tests [`a62e9b3`](https://github.com/rive-app/rive-react/commit/a62e9b3a9aeb51b71c441ea1560eea6431704ee7)
|
||||
- chore: release 3.0.24 [`6b7f113`](https://github.com/rive-app/rive-react/commit/6b7f1132964dafe9783f0a79782a2ba20638c7ce)
|
||||
- fix: make a canvas of size 0 until we calculate the bounds appropriately [`04685c0`](https://github.com/rive-app/rive-react/commit/04685c0bcda26ee0451ab8cc9fc09436e94d04f6)
|
||||
|
||||
#### [v3.0.23](https://github.com/rive-app/rive-react/compare/v3.0.22...v3.0.23)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rive-react",
|
||||
"version": "3.0.24",
|
||||
"version": "3.0.30",
|
||||
"description": "React wrapper around the rive-js library",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/types/index.d.ts",
|
||||
@@ -29,8 +29,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/rive-app/rive-react#readme",
|
||||
"dependencies": {
|
||||
"@rive-app/canvas": "1.0.83",
|
||||
"@rive-app/webgl": "1.0.79"
|
||||
"@rive-app/canvas": "1.0.91",
|
||||
"@rive-app/webgl": "1.0.87"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
RiveState,
|
||||
Dimensions,
|
||||
} from '../types';
|
||||
import { useSize } from '../utils';
|
||||
import { useSize, useDevicePixelRatio } from '../utils';
|
||||
|
||||
type RiveComponentProps = {
|
||||
setContainerRef: RefCallback<HTMLElement>;
|
||||
@@ -86,7 +86,12 @@ export default function useRive(
|
||||
const containerRef = useRef<HTMLElement | null>(null);
|
||||
|
||||
const [rive, setRive] = useState<Rive | null>(null);
|
||||
const [dimensions, setDimensions] = useState<Dimensions>({
|
||||
const [lastContainerDimensions, setLastContainerDimensions] =
|
||||
useState<Dimensions>({
|
||||
height: 0,
|
||||
width: 0,
|
||||
});
|
||||
const [lastCanvasSize, setLastCanvasSize] = useState<Dimensions>({
|
||||
height: 0,
|
||||
width: 0,
|
||||
});
|
||||
@@ -94,6 +99,7 @@ export default function useRive(
|
||||
// Listen to changes in the window sizes and update the bounds when changes
|
||||
// occur.
|
||||
const size = useSize(containerRef);
|
||||
const currentDevicePixelRatio = useDevicePixelRatio();
|
||||
|
||||
const isParamsLoaded = Boolean(riveParams);
|
||||
const options = getOptions(opts);
|
||||
@@ -131,23 +137,42 @@ export default function useRive(
|
||||
}
|
||||
|
||||
const { width, height } = getCanvasDimensions();
|
||||
const boundsChanged =
|
||||
width !== dimensions.width || height !== dimensions.height;
|
||||
if (canvasRef.current && rive && boundsChanged) {
|
||||
if (options.fitCanvasToArtboardHeight) {
|
||||
if (canvasRef.current && rive) {
|
||||
// Check if the canvas parent container bounds have changed and set
|
||||
// new values accordingly
|
||||
const boundsChanged =
|
||||
width !== lastContainerDimensions.width ||
|
||||
height !== lastContainerDimensions.height;
|
||||
if (options.fitCanvasToArtboardHeight && boundsChanged) {
|
||||
containerRef.current.style.height = height + 'px';
|
||||
}
|
||||
if (options.useDevicePixelRatio) {
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
canvasRef.current.width = dpr * width;
|
||||
canvasRef.current.height = dpr * height;
|
||||
canvasRef.current.style.width = width + 'px';
|
||||
canvasRef.current.style.height = height + 'px';
|
||||
} else {
|
||||
// Check if devicePixelRatio may have changed and get new canvas
|
||||
// width/height values to set the size
|
||||
const canvasSizeChanged =
|
||||
width * currentDevicePixelRatio !== lastCanvasSize.width ||
|
||||
height * currentDevicePixelRatio !== lastCanvasSize.height;
|
||||
if (boundsChanged || canvasSizeChanged) {
|
||||
const newCanvasWidthProp = currentDevicePixelRatio * width;
|
||||
const newCanvasHeightProp = currentDevicePixelRatio * height;
|
||||
canvasRef.current.width = newCanvasWidthProp;
|
||||
canvasRef.current.height = newCanvasHeightProp;
|
||||
canvasRef.current.style.width = width + 'px';
|
||||
canvasRef.current.style.height = height + 'px';
|
||||
setLastCanvasSize({
|
||||
width: newCanvasWidthProp,
|
||||
height: newCanvasHeightProp,
|
||||
});
|
||||
}
|
||||
} else if (boundsChanged) {
|
||||
canvasRef.current.width = width;
|
||||
canvasRef.current.height = height;
|
||||
setLastCanvasSize({
|
||||
width: width,
|
||||
height: height,
|
||||
});
|
||||
}
|
||||
setDimensions({ width, height });
|
||||
setLastContainerDimensions({ width, height });
|
||||
|
||||
// Updating the canvas width or height will clear the canvas, so call
|
||||
// startRendering() to redraw the current frame as the animation might
|
||||
@@ -171,7 +196,7 @@ export default function useRive(
|
||||
if (rive) {
|
||||
updateBounds();
|
||||
}
|
||||
}, [rive, size]);
|
||||
}, [rive, size, currentDevicePixelRatio]);
|
||||
|
||||
/**
|
||||
* Ref callback called when the canvas element mounts and unmounts.
|
||||
@@ -190,6 +215,9 @@ export default function useRive(
|
||||
// on an unmounted component in some rare cases
|
||||
if (canvasRef.current) {
|
||||
setRive(r);
|
||||
} else {
|
||||
// If unmounted, cleanup the rive object immediately
|
||||
r.cleanup();
|
||||
}
|
||||
});
|
||||
} else if (canvas === null && canvasRef.current) {
|
||||
@@ -232,12 +260,13 @@ export default function useRive(
|
||||
}, [rive]);
|
||||
|
||||
/**
|
||||
* On unmount, stop rive from rendering.
|
||||
* On unmount, call cleanup to cleanup any WASM generated objects that need
|
||||
* to be manually destroyed.
|
||||
*/
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (rive) {
|
||||
rive.stop();
|
||||
rive.cleanup();
|
||||
setRive(null);
|
||||
}
|
||||
};
|
||||
|
||||
45
src/utils.ts
45
src/utils.ts
@@ -78,3 +78,48 @@ export function useSize(
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for devicePixelRatio changes and set the new value accordingly. This could
|
||||
* happen for reasons such as:
|
||||
* - User moves window from retina screen display to a separate monitor
|
||||
* - User controls zoom settings on the browser
|
||||
*
|
||||
* Source: https://github.com/rexxars/use-device-pixel-ratio/blob/main/index.ts
|
||||
*
|
||||
* @returns dpr: Number - Device pixel ratio; ratio of physical px to resolution in CSS pixels for current device
|
||||
*/
|
||||
export function useDevicePixelRatio() {
|
||||
const dpr = getDevicePixelRatio();
|
||||
const [currentDpr, setCurrentDpr] = useState(dpr);
|
||||
|
||||
useEffect(() => {
|
||||
const canListen = typeof window !== 'undefined' && 'matchMedia' in window;
|
||||
if (!canListen) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateDpr = () => {
|
||||
const newDpr = getDevicePixelRatio();
|
||||
setCurrentDpr(newDpr);
|
||||
};
|
||||
const mediaMatcher = window.matchMedia(
|
||||
`screen and (resolution: ${currentDpr}dppx)`
|
||||
);
|
||||
mediaMatcher.addEventListener('change', updateDpr);
|
||||
|
||||
return () => {
|
||||
mediaMatcher.removeEventListener('change', updateDpr);
|
||||
};
|
||||
}, [currentDpr]);
|
||||
|
||||
return currentDpr;
|
||||
}
|
||||
|
||||
export function getDevicePixelRatio(): number {
|
||||
const hasDprProp =
|
||||
typeof window !== 'undefined' &&
|
||||
typeof window.devicePixelRatio === 'number';
|
||||
const dpr = hasDprProp ? window.devicePixelRatio : 1;
|
||||
return Math.min(Math.max(1, dpr), 3);
|
||||
}
|
||||
|
||||
@@ -102,16 +102,16 @@ describe('useRive', () => {
|
||||
expect(resizeToCanvasMock).toBeCalled();
|
||||
});
|
||||
|
||||
it('stops the rive object on unmount', async () => {
|
||||
it('calls cleanup on the rive object on unmount', async () => {
|
||||
const params = {
|
||||
src: 'file-src',
|
||||
};
|
||||
|
||||
const stopMock = jest.fn();
|
||||
const cleanupMock = jest.fn();
|
||||
|
||||
const riveMock = {
|
||||
...baseRiveMock,
|
||||
stop: stopMock,
|
||||
cleanup: cleanupMock,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
@@ -127,7 +127,7 @@ describe('useRive', () => {
|
||||
|
||||
unmount();
|
||||
|
||||
expect(stopMock).toBeCalled();
|
||||
expect(cleanupMock).toBeCalled();
|
||||
});
|
||||
|
||||
it('sets the a bounds with the devicePixelRatio by default', async () => {
|
||||
@@ -424,4 +424,31 @@ describe('useRive', () => {
|
||||
expect(canvasSpy).toHaveStyle('height: 100px');
|
||||
expect(canvasSpy).toHaveStyle('width: 100px');
|
||||
});
|
||||
|
||||
it('updates the canvas dimensions and size if there is a new canvas size calculation', async () => {
|
||||
const params = {
|
||||
src: 'file-src',
|
||||
};
|
||||
|
||||
window.devicePixelRatio = 2;
|
||||
|
||||
// @ts-ignore
|
||||
mocked(rive.Rive).mockImplementation(() => baseRiveMock);
|
||||
|
||||
const canvasSpy = document.createElement('canvas');
|
||||
const containerSpy = document.createElement('div');
|
||||
jest.spyOn(containerSpy, 'clientWidth', 'get').mockReturnValue(100);
|
||||
jest.spyOn(containerSpy, 'clientHeight', 'get').mockReturnValue(100);
|
||||
|
||||
const { result } = renderHook(() => useRive(params));
|
||||
|
||||
await act(async () => {
|
||||
result.current.setCanvasRef(canvasSpy);
|
||||
result.current.setContainerRef(containerSpy);
|
||||
controlledRiveloadCb();
|
||||
});
|
||||
|
||||
expect(canvasSpy).toHaveAttribute('width', '200');
|
||||
expect(canvasSpy).toHaveAttribute('height', '200');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user