Freehand sketch on canvas based on @shopify/react-native-skia
You need to install following dependencies
"@shopify/react-native-skia": ">=1.0.0",
"react": ">=18.0.0",
"react-native": ">=0.72.0",
"react-native-gesture-handler": ">=2.0.0",
"react-native-reanimated": ">=3.0.0"
import FreeCanvas from 'react-native-free-canvas';
const App = () => {
return (
<>
<FreeCanvas
// style={{flex: 1}}
style={styles.flex1} //avoid using a new Object to prevent unnecessary re-rendering
/>
</>
)
};
import {CornerPathEffect} from '@shopify/react-native-skia';
const effects = useMemo(() => <CornerPathEffect r={32} />, []);
// Add CornerPathEffect component to pathEffect props
<FreeCanvas
// style={{flex: 1}}
style={styles.flex1}
pathEffect={effects}
/>
{
style?: StyleProp<ViewStyle>;
strokeColor?: string | SharedValue<string>;
strokeWidth?: number | SharedValue<number>;
backgroundColor?: string | SharedValue<string>;
background?: React.ReactNode; // Should be Skia component
foreground?: React.ReactNode; // Should be Skia component
pathEffect?: React.ReactNode; // Should be Skia Path Effects (https://shopify.github.io/react-native-skia/docs/path-effects)
zoomable?: boolean;
onDrawEnd?: () => void;
onTranslate?: (x: number, y: number) => void; // should be a worklet function, it runs on UI thread
onScale?: (scale: number) => void; // should be a worklet function, it runs on UI thread
onTransformOriginChange?: (x: number, y: number) => void; // should be a worklet function, it runs on UI thread
}
The order of the transform and scale in animated style for the Canvas while zooming should be:
{
transform: [
{ translateX: translateSharedVal.value.x },
{ translateY: translateSharedVal.value.y },
{ scale: scaleSharedVal.value },
],
transformOrigin: originSharedVal.value.concat([0]),
}
{
reset: () => void;
resetZoom: (duration?: number) => void;
undo: (step?: number) => void;
toBase64: (
fmt?: ImageFormat,
quality?: number,
) => Promise<string | undefined>;
getSnapshot: () => Promise<SkImage | undefined> | undefined;
toPaths: () => DrawnPath[];
drawPaths: (paths: DrawnPath[]) => void;
translateSharedValue: SharedValue<{ x: number; y: number }>;
scaleSharedValue: SharedValue<number>;
transformOriginSharedValue: SharedValue<[number, number]>;
}
wobsoriano/rn-perfect-sketch-canvas A React Native component for drawing perfect pressure-sensitive freehand lines using perfect-freehand and Skia renderer.