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
相关产品推荐
相关产品推荐

