You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 22:45:37