Compare commits

...

13 Commits

Author SHA1 Message Date
avivian
78491f5819 chore: release 3.0.28 2022-10-20 09:44:48 +00:00
Arthur Vivian
39edb88a19 Bump canvas and webgl dependencies to fix alignment memory leaks 2022-10-20 10:42:06 +01:00
zplata
fd1a1653b1 chore: release 3.0.27 2022-10-04 17:56:49 +00:00
Zach Plata
8d7f0ab28c Fix: Bump wasm to accomodate clipping bug on nested artboards 2022-10-04 12:53:17 -05:00
zplata
2a2e532564 chore: release 3.0.26 2022-09-22 17:15:22 +00:00
Zach Plata
2b1aa01a87 fix: Adjust canvas size if devicePixelRatio changes for any reaason 2022-09-22 12:12:32 -05:00
zplata
06c4e2aea3 chore: release 3.0.25 2022-09-21 14:23:55 +00:00
Zach Plata
819bd51ea9 patch: bump js runtime dependency to address content security policy issue in WASM build 2022-09-21 09:20:55 -05:00
zplata
6b7f113296 chore: release 3.0.24 2022-09-15 15:56:54 +00:00
Zach Plata
a62e9b3a9a add tests 2022-09-15 10:53:36 -05:00
Zach Plata
04685c0bcd fix: make a canvas of size 0 until we calculate the bounds appropriately 2022-09-15 10:53:36 -05:00
avivian
48fd9f9d80 chore: release 3.0.23 2022-08-31 10:27:17 +00:00
Arthur Vivian
3c578b730f Bump runtime version to fix broken version 2022-08-31 11:24:05 +01:00
5 changed files with 181 additions and 18 deletions

View File

@@ -4,8 +4,22 @@ 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.28](https://github.com/rive-app/rive-react/compare/v3.0.23...v3.0.28)
- Bump canvas and webgl dependencies to fix alignment memory leaks [`39edb88`](https://github.com/rive-app/rive-react/commit/39edb88a19aaff478e4e9cbeeef58414f28fdb60)
#### [v3.0.23](https://github.com/rive-app/rive-react/compare/v3.0.22...v3.0.23)
> 31 August 2022
- chore: release 3.0.23 [`48fd9f9`](https://github.com/rive-app/rive-react/commit/48fd9f9d8048ef098ed7550e6da0d3a4eb69148e)
- Bump runtime version to fix broken version [`3c578b7`](https://github.com/rive-app/rive-react/commit/3c578b730f82059469393522722316f2ad3a61d3)
#### [v3.0.22](https://github.com/rive-app/rive-react/compare/v3.0.21...v3.0.22)
> 30 August 2022
- chore: release 3.0.22 [`7a46886`](https://github.com/rive-app/rive-react/commit/7a468861336861361f4fceae45616f001bf4b448)
- Update @rive-app/canvas and @rive-app/webgl dependencies to support non node builds [`092049d`](https://github.com/rive-app/rive-react/commit/092049d20f6f955a0528831d2b5e15087328bc75)
#### [v3.0.21](https://github.com/rive-app/rive-react/compare/v3.0.20...v3.0.21)

View File

@@ -1,6 +1,6 @@
{
"name": "rive-react",
"version": "3.0.22",
"version": "3.0.28",
"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.81",
"@rive-app/webgl": "1.0.77"
"@rive-app/canvas": "1.0.89",
"@rive-app/webgl": "1.0.85"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"

View File

@@ -13,7 +13,7 @@ import {
RiveState,
Dimensions,
} from '../types';
import { useSize } from '../utils';
import { useSize, useDevicePixelRatio } from '../utils';
type RiveComponentProps = {
setContainerRef: RefCallback<HTMLElement>;
@@ -39,7 +39,11 @@ function RiveComponent({
className={className}
{...(!className && { style: containerStyle })}
>
<canvas ref={setCanvasRef} style={{ verticalAlign: 'top' }} {...rest} />
<canvas
ref={setCanvasRef}
style={{ verticalAlign: 'top', width: 0, height: 0 }}
{...rest}
/>
</div>
);
}
@@ -82,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,
});
@@ -90,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);
@@ -127,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
@@ -167,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.

View File

@@ -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);
}

View File

@@ -376,4 +376,79 @@ describe('useRive', () => {
);
expect(container.firstChild).not.toHaveStyle('width: 50%');
});
it('has a canvas size of 0 by default', async () => {
const params = {
src: 'file-src',
};
// @ts-ignore
mocked(rive.Rive).mockImplementation(() => baseRiveMock);
const canvasSpy = document.createElement('canvas');
const { result } = renderHook(() => useRive(params));
await act(async () => {
result.current.setCanvasRef(canvasSpy);
controlledRiveloadCb();
});
const { RiveComponent: RiveTestComponent } = result.current;
const { container } = render(<RiveTestComponent />);
expect(container.querySelector('canvas')).toHaveStyle('width: 0');
});
it('sets the canvas width and height after calculating the container size', async () => {
const params = {
src: 'file-src',
};
global.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).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');
});
});