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

React Native Skia中Canvas内Rect初始无法居中的问题排查

React Native Skia Rect初始渲染不居中,热重载后恢复正常的解决方法

问题分析

初始启动或刷新时,Rect基于size的初始值{width:0, height:0}计算x坐标(0/2 -50 = -50),Skia会自动将超出画布的x值修正为0,导致Rect左对齐。虽然onSize或onLayout能正确获取画布实际尺寸并更新size,但直接在Rect的x属性中使用size.value.width时,Reanimated可能未正确跟踪该依赖的变化,无法触发Canvas的重绘,直到热重载时size已有正确值,才会绘制出居中效果。

解决方案

方案1:使用Skia内置的Align组件(推荐)

无需手动计算坐标,利用Skia的Align组件自动实现居中,适配所有渲染阶段:

import { Canvas, Rect, Align } from "@shopify/react-native-skia";

// ...

<Canvas style={{height:200, margin:30, backgroundColor:"purple"}}>
  <Align align="center" horizontalAnchor="center" verticalAnchor="center">
    <Rect width={100} height={100} color="lightblue" />
  </Align>
</Canvas>

方案2:用useDerivedValue跟踪尺寸变化

通过useDerivedValue明确订阅size的变化,确保Rect的x坐标能实时更新并触发重绘:

import { useSharedValue, useDerivedValue } from "react-native-reanimated";
import { Canvas, Rect } from "@shopify/react-native-skia";

// ...

const size = useSharedValue({ width: 0, height: 0 });
// 派生Rect的x坐标,依赖size的变化
const rectX = useDerivedValue(() => {
  return size.value.width / 2 - 50;
}, [size]);

// ...

<Canvas onSize={size} style={{height:200, margin:30, backgroundColor:"purple"}}>
  <Rect x={rectX} width={100} height={100} color="lightblue" />
</Canvas>

方案3:强制Canvas响应尺寸更新

如果坚持直接使用size.value,可以给Canvas添加一个基于size的key,强制尺寸变化时重新渲染Canvas:

<Canvas 
  onSize={size} 
  style={{height:200, margin:30, backgroundColor:"purple"}}
  key={`${size.value.width}-${size.value.height}`}
>
  <Rect x={size.value.width/2 - 50} width={100} height={100} color="lightblue" />
</Canvas>

验证说明

  • 方案1无需手动计算,是Skia官方推荐的布局方式,兼容性最好
  • 方案2通过Reanimated的派生值机制,确保状态变化能正确传递到Skia组件
  • 方案3通过key触发组件重渲染,属于兜底方案,适合快速调试

内容的提问来源于stack exchange,提问作者Victor Chelaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:55:25