如何为react-native-skia的Path或Line一端实现动画效果
问题:React Native Skia中Path/Line端点无法跟随Circle同步移动
当前代码无报错,但平移手势操作时,Circle组件可正常跟随移动,Path和Line的端点却无法同步移动。期望实现Path或Line的端点跟随Circle同步移动(功能正常后会移除坐标中的±20偏移)。
核心问题
- Path和Line组件仅接受number类型的坐标参数(如
skiaX.current、currentX.value),但直接使用这些值时,组件渲染无法同步更新状态 - Circle组件可直接传入
SkiaMutableValue类型的skiaX/skiaY实现动态更新,但尝试将SkiaMutableValue直接用于Path的path字符串拼接时,会触发类型错误:Operator '+' cannot be applied to types 'SkiaMutableValue' and 'number'
解决方法
以下两种方案均可实现端点与Circle同步移动:
方案1:使用Skia的useComputedValue构建响应式路径(推荐)
利用Skia提供的useComputedValue监听skiaX/skiaY的变化,动态构建Path对象和坐标点:
// 补充导入useComputedValue import {Canvas, Circle, Line, vec, Path, Rect, Skia, useSharedValueEffect, useValue, useComputedValue} from '@shopify/react-native-skia'; // 在组件内部添加 const path = useComputedValue(() => { const p = Skia.Path.Make(); p.moveTo(skiaX.current - 20, skiaY.current + 20); p.lineTo(width / 2, height / 2); return p; }, [skiaX, skiaY]); const lineP1 = useComputedValue(() => vec(skiaX.current + 20, skiaY.current + 20), [skiaX, skiaY]); // 替换原Path和Line的渲染代码 <Path path={path} style="stroke" strokeWidth={strokeWidth} strokeCap="round" color={'orange'} /> <Line p1={lineP1} p2={vec(width/2, height/2)} color="white" style="stroke" strokeWidth={strokeWidth} />
方案2:使用Reanimated的useAnimatedProps传递动态属性
通过Reanimated的动画属性更新能力,让Path和Line的属性响应currentX/currentY的变化:
// 补充导入useAnimatedProps import {Canvas, Circle, Line, vec, Path, Rect, Skia, useSharedValueEffect, useValue, useAnimatedProps} from '@shopify/react-native-skia'; // 在组件内部添加 const pathAnimatedProps = useAnimatedProps(() => { return { path: `M ${currentX.value - 20} ${currentY.value + 20} L ${width/2} ${height/2}` }; }, [currentX, currentY]); const lineAnimatedProps = useAnimatedProps(() => { return { p1: vec(currentX.value + 20, currentY.value + 20) }; }, [currentX, currentY]); // 替换原Path和Line的渲染代码 <Path animatedProps={pathAnimatedProps} style="stroke" strokeWidth={strokeWidth} strokeCap="round" color={'orange'} /> <Line animatedProps={lineAnimatedProps} p2={vec(width/2, height/2)} color="white" style="stroke" strokeWidth={strokeWidth} />
原理说明
直接在JSX中使用currentX.value或skiaX.current时,这些值仅在组件初始渲染时被读取,后续状态更新不会触发属性重新计算。而useComputedValue和useAnimatedProps可以监听对应响应式值的变化,自动更新组件属性,实现动态同步。
内容的提问来源于stack exchange,提问作者whatthedev
相关产品推荐
相关产品推荐

