animation-with-worklets
npx skills add https://github.com/sovranbitcoin/sovran --skill animation-with-worklets
Agent 安装分布
Skill 文档
Worklet Scheduling
Overview
Guidelines for scheduling functions between JavaScript and UI threads using React Native Worklets. This skill covers when and how to use scheduleOnRN and scheduleOnUI, proper function definition patterns, and avoiding unnecessary worklet directives.
When to Apply
Reference these guidelines when:
- Scheduling functions to run on UI thread from JS thread
- Calling JS thread functions from UI thread worklets
- Working with
useAnimatedReactionor gesture handlers - Batching shared value updates
- Implementing cross-thread communication in animations
Key Guidelines
Don’t Use ‘worklet’ Directive Unless Explicitly Asked
Never use the "worklet" directive unless explicitly requested. In 99.9% of cases, there is no need to use it. scheduleOnUI handles worklet conversion automatically, so the directive is unnecessary. This also applies to gesture detector callbacks – you don’t need to add the "worklet" directive in gesture handler callbacks.
Use scheduleOnRN and scheduleOnUI Instead of runOnJS and runOnUI
Use scheduleOnRN and scheduleOnUI from react-native-worklets instead of runOnJS and runOnUI from react-native-reanimated.
Don’t do this:
import { runOnJS, runOnUI } from "react-native-reanimated";
Instead, do this:
import { scheduleOnRN, scheduleOnUI } from "react-native-worklets";
Type Definitions
function scheduleOnRN<Args extends unknown[], ReturnValue>(
fun:
| ((...args: Args) => ReturnValue)
| RemoteFunction<Args, ReturnValue>
| WorkletFunction<Args, ReturnValue>,
...args: Args
): void;
function scheduleOnUI<Args extends unknown[], ReturnValue>(
fun: (...args: Args) => ReturnValue,
...args: Args
): void;
Usage Patterns
Always Define Functions Outside Using useCallback
Both scheduleOnRN and scheduleOnUI follow the same usage pattern: always define the function outside using useCallback and pass the function reference (not inline arrow functions).
When to use:
scheduleOnRN: Call JavaScript thread functions from UI thread worklets (like inuseAnimatedReaction, gesture handlers, oruseAnimatedStyle)scheduleOnUI: Schedule functions to run on the UI thread
Don’t do this â inline arrow function:
// â scheduleOnRN with inline function
useAnimatedReaction(
() => currentIndex.get(),
(nextIndex) => {
scheduleOnRN(() => {
setState(newValue);
});
}
);
// â scheduleOnUI with inline function
scheduleOnUI(() => {
scale.set(withSpring(1.2));
});
Instead, do this â define function outside:
// â
scheduleOnRN - JS thread function
const updateState = useCallback(() => {
setState(newValue);
}, [dependencies]);
useAnimatedReaction(
() => currentIndex.get(),
(nextIndex) => {
scheduleOnRN(updateState); // pass function reference
}
);
// â
scheduleOnUI - UI thread function
const updateAnimations = useCallback(() => {
scale.set(withSpring(1.2));
opacity.set(withSpring(0.8));
}, []);
scheduleOnUI(updateAnimations); // pass function reference
Passing Arguments
Arguments are passed directly (not as an array) using rest parameter syntax:
// Single argument
const updateState = useCallback((newValue: number) => {
setState(newValue);
}, []);
scheduleOnRN(updateState, newValue); // â
correct
// Multiple arguments
const handleUpdate = useCallback((index: number, value: string) => {
setState({ index, value });
}, []);
scheduleOnRN(handleUpdate, index, value); // â
correct - pass directly, not as array
scheduleOnUI(handleUpdate, index, value); // â
same pattern for scheduleOnUI
Common Use Cases
scheduleOnRN Use Cases
- React state setters (
setState,setExtendedSlides, etc.) - API calls or side effects
- Video player controls (
pause,resume,seek) - Haptic feedback
- Navigation functions
Example:
// scheduleOnRN example
const pause = useCallback(() => {
videoPlayerRef.current?.pause();
}, []);
useAnimatedReaction(
() => isDragging.get(),
(current) => {
if (current) {
scheduleOnRN(pause);
}
}
);
scheduleOnUI Use Cases
- Batch multiple shared value updates in the same frame
- UI thread worklet operations
Example:
// scheduleOnUI example - batch updates
const batchUpdates = useCallback(() => {
scale.set(withSpring(1.2));
opacity.set(withSpring(0.8));
}, []);
scheduleOnUI(batchUpdates);
Benefits
- Automatic Worklet Conversion:
scheduleOnUIhandles worklet conversion automatically - Better Performance: Batching updates reduces UI thread overhead
- Type Safety: Better TypeScript support with proper type definitions
- Cleaner Code: No need for
"worklet"directive in most cases - Consistent API: Unified approach for cross-thread communication