diff --git a/apps/docs/docs/animations/reanimated2.md b/apps/docs/docs/animations/reanimated2.md
deleted file mode 100644
index 1641b47eda..0000000000
--- a/apps/docs/docs/animations/reanimated2.md
+++ /dev/null
@@ -1,86 +0,0 @@
----
-id: reanimated2
-title: Reanimated 2
-sidebar_label: Reanimated 2
-slug: /animations/reanimated2
----
-
-:::info
-
-The Reanimated 2 integration operates on the JS thread. We recommend using Reanimated 3 when possible for better performance and features. For more details, refer to the [Reanimated 3 support section](/docs/animations/animations).
-
-:::
-
-While Reanimated v2 is fully integrated and functional, there are two important caveats to consider:
-* [Animations are executed on the JS thread](#animations-on-the-js-thread)
-* [Working with Host Objects](#working-with-host-objects)
-
-## Animations on the JS Thread
-
-In the example below, the animation runs on the JS thread due to the use of Reanimated v2, even though the animation itself is fairly simple.
-
-```tsx twoslash
-import {useEffect} from "react";
-import {Canvas, Rect, mix} from "@shopify/react-native-skia";
-import {useSharedValue, withRepeat, withTiming, useDerivedValue} from "react-native-reanimated";
-
-const MyComponent = () => {
- const progress = useSharedValue(0);
-
- useEffect(() => {
- progress.value = withRepeat(withTiming(1, { duration: 3000 }), -1, true);
- }, [progress]);
-
- const x = useDerivedValue(() => {
- return mix(progress.value, 0, 100);
- });
-
- return (
-
- );
-};
-```
-
-## Working with Host Objects
-
-When your animation involves Skia objects and Reanimated v2, you must ensure that the code explicitly runs on the JS thread. To facilitate this, you can use the `useDerivedValueOnJS` hook.
-
-```tsx twoslash
-import {useDerivedValueOnJS, Skia} from "@shopify/react-native-skia";
-import {useDerivedValue, useSharedValue} from "react-native-reanimated";
-
-const path = Skia.Path.MakeFromSVGString("M 344 172 Q 344 167 343.793 163")!;
-const path2 = Skia.Path.MakeFromSVGString("M 347 169 Q 344 167 349 164")!;
-
-const progress = useSharedValue(0.5);
-
-// ❌ This will crash as it's running on the worklet thread
-useDerivedValue(() => path.interpolate(path2, progress.value));
-
-// ✅ This will work as expected since it runs on the JS thread
-useDerivedValueOnJS(() => path.interpolate(path2, progress.value), [progress]);
-```
-
-Similarly, when using host objects inside a gesture handler, ensure that its execution is on the JS thread:
-
-```tsx twoslash
-import {vec} from "@shopify/react-native-skia";
-import {Gesture} from "react-native-gesture-handler";
-import {useSharedValue} from "react-native-reanimated";
-
-const pos = useSharedValue(vec(0, 0));
-
-// ❌ This will crash as it's running on the worklet thread
-Gesture.Pan().onChange(e => pos.value = vec(e.x, 0));
-
-// ✅ This will work as expected since it runs on the JS thread
-Gesture.Pan().runOnJS(true).onChange(e => pos.value = vec(e.x, 0));
-```
\ No newline at end of file
diff --git a/apps/docs/docs/animations/reanimated3.md b/apps/docs/docs/animations/reanimated3.md
index d2dcfd0669..02ddb3e3f6 100644
--- a/apps/docs/docs/animations/reanimated3.md
+++ b/apps/docs/docs/animations/reanimated3.md
@@ -5,8 +5,7 @@ sidebar_label: Animations
slug: /animations/animations
---
-React Native Skia offers integration with [Reanimated v3](https://docs.swmansion.com/react-native-reanimated/), enabling the execution of animations on the UI thread.
-This integration is available starting from Reanimated v3. If you are using Reanimated v2, refer to the [Reanimated 2 support section](/docs/animations/reanimated2).
+React Native Skia offers integration with [Reanimated v3 and above](https://docs.swmansion.com/react-native-reanimated/), enabling the execution of animations on the UI thread.
React Native Skia supports the direct usage of Reanimated's shared and derived values as properties. There is no need for functions like `createAnimatedComponent` or `useAnimatedProps`; simply pass the Reanimated values directly as properties.
diff --git a/apps/docs/sidebars.js b/apps/docs/sidebars.js
index 52f464f48c..571bbb46cc 100644
--- a/apps/docs/sidebars.js
+++ b/apps/docs/sidebars.js
@@ -140,7 +140,6 @@ const sidebars = {
"animations/gestures",
"animations/hooks",
"animations/textures",
- "animations/reanimated2",
],
},
{
diff --git a/packages/skia/src/external/reanimated/index.ts b/packages/skia/src/external/reanimated/index.ts
index fe7bc42c3e..a92b153312 100644
--- a/packages/skia/src/external/reanimated/index.ts
+++ b/packages/skia/src/external/reanimated/index.ts
@@ -1,5 +1,4 @@
export * from "./useAnimatedImageValue";
-export * from "./useDerivedValueOnJS";
export * from "./renderHelpers";
export * from "./interpolators";
export * from "./textures";
diff --git a/packages/skia/src/external/reanimated/renderHelpers.ts b/packages/skia/src/external/reanimated/renderHelpers.ts
index 371c8b0090..a1b4dcd1e2 100644
--- a/packages/skia/src/external/reanimated/renderHelpers.ts
+++ b/packages/skia/src/external/reanimated/renderHelpers.ts
@@ -6,7 +6,6 @@ import type { Node } from "../../dom/types";
import Rea from "./ReanimatedProxy";
-export let HAS_REANIMATED = false;
export let HAS_REANIMATED_3 = false;
try {
// This logic is convoluted but necessary
@@ -16,7 +15,6 @@ try {
const reanimatedVersion =
require("react-native-reanimated/package.json").version;
require("react-native-reanimated");
- HAS_REANIMATED = !!reanimatedVersion;
if (
reanimatedVersion &&
(reanimatedVersion >= "3.0.0" || reanimatedVersion.includes("3.0.0-"))
@@ -24,13 +22,13 @@ try {
HAS_REANIMATED_3 = true;
}
} catch (e) {
- HAS_REANIMATED = false;
+ // do nothing
}
const _bindings = new WeakMap, unknown>();
export const unbindReanimatedNode = (node: Node) => {
- if (!HAS_REANIMATED) {
+ if (!HAS_REANIMATED_3) {
return;
}
const previousMapperId = _bindings.get(node);
@@ -40,7 +38,7 @@ export const unbindReanimatedNode = (node: Node) => {
};
export function extractReanimatedProps(props: AnimatedProps) {
- if (!HAS_REANIMATED) {
+ if (!HAS_REANIMATED_3) {
return [props, {}];
}
const reanimatedProps = {} as AnimatedProps;
@@ -60,50 +58,12 @@ export function extractReanimatedProps(props: AnimatedProps) {
return [otherProps, reanimatedProps];
}
-function bindReanimatedProps2(
- container: Container,
- node: Node,
- reanimatedProps: AnimatedProps
-) {
- const sharedValues = Object.values(reanimatedProps);
- const previousMapperId = _bindings.get(node);
- if (previousMapperId !== undefined) {
- Rea.stopMapper(previousMapperId as number);
- }
- if (sharedValues.length > 0) {
- const viewId = container.getNativeId();
- const { SkiaViewApi } = global;
- const updateProps = () => {
- for (const propName in reanimatedProps) {
- node && node.setProp(propName, reanimatedProps[propName].value);
- }
- // On React Native we use the SkiaViewApi to redraw because it can
- // run on the worklet thread (container.redraw can't)
- // if SkiaViewApi is undefined, we are on web and container.redraw()
- // can safely be invoked
- if (SkiaViewApi) {
- SkiaViewApi.requestRedraw(viewId);
- } else {
- container.redraw();
- }
- };
- const mapperId = Rea.startMapper(() => {
- "worklet";
- Rea.runOnJS(updateProps)();
- }, sharedValues);
- _bindings.set(node, mapperId);
- }
-}
-
export function bindReanimatedProps(
container: Container,
node: Node,
reanimatedProps: AnimatedProps
) {
- if (HAS_REANIMATED && !HAS_REANIMATED_3) {
- return bindReanimatedProps2(container, node, reanimatedProps);
- }
- if (!HAS_REANIMATED) {
+ if (!HAS_REANIMATED_3) {
return;
}
const sharedValues = Object.values(reanimatedProps);
diff --git a/packages/skia/src/external/reanimated/useDerivedValueOnJS.ts b/packages/skia/src/external/reanimated/useDerivedValueOnJS.ts
deleted file mode 100644
index e52ba01e2a..0000000000
--- a/packages/skia/src/external/reanimated/useDerivedValueOnJS.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { useEffect, useMemo } from "react";
-
-import Rea from "./ReanimatedProxy";
-
-export const useDerivedValueOnJS = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- fn: () => any,
- deps: unknown[]
-) => {
- const init = useMemo(() => fn(), [fn]);
- const value = Rea.useSharedValue(init);
- useEffect(() => {
- const mapperId = Rea.startMapper(() => {
- "worklet";
- Rea.runOnJS(fn)();
- }, deps);
- return () => Rea.stopMapper(mapperId);
- }, [deps, fn]);
- return value;
-};
diff --git a/packages/skia/src/sksg/Container.ts b/packages/skia/src/sksg/Container.ts
index 20a78e2c27..51ffb11001 100644
--- a/packages/skia/src/sksg/Container.ts
+++ b/packages/skia/src/sksg/Container.ts
@@ -2,10 +2,6 @@ import { type SharedValue } from "react-native-reanimated";
import Rea from "../external/reanimated/ReanimatedProxy";
import type { Skia, SkCanvas } from "../skia/types";
-import {
- HAS_REANIMATED,
- HAS_REANIMATED_3,
-} from "../external/reanimated/renderHelpers";
import { createDrawingContext } from "./DrawingContext";
import type { Node } from "./nodes";
@@ -40,9 +36,6 @@ export class Container {
set root(root: Node[]) {
const isOnscreen = this.nativeId !== -1;
- if (HAS_REANIMATED && !HAS_REANIMATED_3) {
- throw new Error("React Native Skia only supports Reanimated 3 and above");
- }
if (isOnscreen) {
if (this.mapperId !== null) {
Rea.stopMapper(this.mapperId);
@@ -62,9 +55,6 @@ export class Container {
redraw() {
const isOnscreen = this.nativeId !== -1;
- if (HAS_REANIMATED && !HAS_REANIMATED_3) {
- throw new Error("React Native Skia only supports Reanimated 3 and above");
- }
if (isOnscreen) {
const { nativeId, Skia, root } = this;
Rea.runOnUI(() => {