Skip to content

Commit

Permalink
Merge pull request #1577 from Shopify/onsize
Browse files Browse the repository at this point in the history
Add support for shared values in onSize
  • Loading branch information
chrfalch authored May 23, 2023
2 parents c37c429 + 0e162e5 commit c6b68ed
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/docs/animations/values.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const Demo = () => {

## Canvas Size

The `onSize` property will update the provided Skia Value with the current canvas size when the Canvas is resized.
The `onSize` property will update the provided Skia Value with the current canvas size when the Canvas is resized. This property can also be a Reanimated shared value (see [reanimated integration](/docs/animations/reanimated)).

```tsx twoslash
import React from "react";
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/canvas/canvas.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Behind the scenes, it is using its own React renderer.
| ref? | `Ref<SkiaView>` | Reference to the `SkiaView` object |
| mode? | `default` or `continuous` | By default, the canvas is only updated when the drawing tree or animation values change. With `mode="continuous"`, the canvas will redraw on every frame |
| onTouch? | `TouchHandler` | Touch handler for the Canvas (see [touch handler](/docs/animations/touch-events#usetouchhandler)) |
| onSize? | `SkiaMutableValue<Size>` | Skia value to which the canvas size will be assigned (see [canvas size](/docs/animations/values#canvas-size)) |
| onSize? | `SkiaMutableValue<Size>` or `SharedValue<Size>` | Skia or Reanimated value to which the canvas size will be assigned (see [canvas size](/docs/animations/values#canvas-size)) |
| onLayout? | `NativeEvent<LayoutEvent>` | Invoked on mount and on layout changes (see [onLayout](https://reactnative.dev/docs/view#onlayout)) |

## Getting the Canvas size
Expand Down
22 changes: 21 additions & 1 deletion package/src/renderer/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import { Skia } from "../skia/Skia";
import type { TouchHandler, SkiaBaseViewProps } from "../views";
import type { SkiaValue } from "../values/types";
import { JsiDrawingContext } from "../dom/types";
import { useValue } from "../values";

import { SkiaRoot } from "./Reconciler";
import { NATIVE_DOM } from "./HostComponents";
import { isValue } from "./processors";

export const useCanvasRef = () => useRef<SkiaDomView>(null);

Expand All @@ -31,9 +33,27 @@ export interface CanvasProps extends SkiaBaseViewProps {

export const Canvas = forwardRef<SkiaDomView, CanvasProps>(
(
{ children, style, debug, mode, onTouch, onSize, ...props },
{
children,
style,
debug,
mode,
onTouch,
onSize: onSizeReanimatedOrSkia,
...props
},
forwardedRef
) => {
const size = useValue({ width: 0, height: 0 });
const onSize = isValue(onSizeReanimatedOrSkia)
? onSizeReanimatedOrSkia
: size;
useEffect(() => {
if (!isValue(onSizeReanimatedOrSkia) && onSizeReanimatedOrSkia) {
return size.addListener((v) => (onSizeReanimatedOrSkia.value = v));
}
return undefined;
}, [onSizeReanimatedOrSkia, size]);
const innerRef = useCanvasRef();
const ref = useCombinedRefs(forwardedRef, innerRef);
const redraw = useCallback(() => {
Expand Down
7 changes: 6 additions & 1 deletion package/src/views/SkiaDomView.web.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Skia } from "../skia";
import type { SkCanvas } from "../skia/types";
import { JsiDrawingContext } from "../dom/types/DrawingContext";
import { isValue } from "../renderer/processors/Animations/Animations";

import { SkiaBaseWebView } from "./SkiaBaseWebView";
import type { SkiaDomViewProps, TouchInfo } from "./types";
Expand All @@ -16,7 +17,11 @@ export class SkiaDomView extends SkiaBaseWebView<SkiaDomViewProps> {
}
if (this.props.onSize) {
const { width, height } = this.getSize();
this.props.onSize.current = { width, height };
if (isValue(this.props.onSize)) {
this.props.onSize.current = { width, height };
} else {
this.props.onSize.value = { width, height };
}
}
if (this.props.root) {
const ctx = new JsiDrawingContext(Skia, canvas);
Expand Down
3 changes: 2 additions & 1 deletion package/src/views/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
SkSize,
} from "../skia/types";
import type { SkiaMutableValue, SkiaValue } from "../values";
import type { SharedValueType } from "../renderer/processors/Animations/Animations";

export type DrawMode = "continuous" | "default";

Expand Down Expand Up @@ -97,7 +98,7 @@ export interface SkiaBaseViewProps extends ViewProps {
* Pass an animated value to the onSize property to get updates when
* the Skia view is resized.
*/
onSize?: SkiaMutableValue<SkSize>;
onSize?: SkiaMutableValue<SkSize> | SharedValueType<SkSize>;
}

export interface SkiaDrawViewProps extends SkiaBaseViewProps {
Expand Down

0 comments on commit c6b68ed

Please sign in to comment.