我想使用react-native-skia (
https://github.com/Shopify/react-native-skia)将Skia
Rect
置于React Native中的Skia Canvas
中。如果我刷新我的应用程序,或者重新启动它,矩形不会居中,但如果我更改代码并保存它(导致热重载),矩形就会居中。我怀疑这意味着我正在做一些无序的事情,或者可能没有手动执行某种刷新,例如使表面无效,但我不确定。
我正在使用以下代码(为了简洁起见,进行了简化):
const size = useSharedValue({ width: 0, height: 0 });
...
<Canvas onSize={size} style={{height:200, margin:30, backgroundColor:"purple"}}>
<Rect x={size.value.width/2 - 50} width={100} height={100} color="lightblue" />
</Canvas>
...
我正在按照react-native-skia文档中的建议使用react-native-reanimated中的useSharedValue:
https://shopify.github.io/react-native-skia/docs/canvas/overview
上面的代码导致绘制的矩形中心左对齐:
如果我更改任何代码并保存文件,应用程序会热重载并且矩形会出现在正确的位置:
为什么矩形最初渲染在错误的位置?我意识到我正在设置
{ width: 0, height: 0 }
的值,但我预计当执行初始布局并且 Canvas 根据显式属性和 Flex 值获取其实际大小时,该值将通过 onSize 事件被覆盖。
我还尝试处理 onLayout 事件,看看我是否可以响应该更改:
const size = useSharedValue({ width: 0, height: 0 });
const handleLayout = (event: LayoutChangeEvent) => {
const { width, height } = event.nativeEvent.layout;
console.log(`Width: ${width}, Height: ${height}`);
size.value = {width:width, height:height};
};
...
<Canvas onSize={size} onLayout={handleLayout} style={{height:200, margin:30, backgroundColor:"purple"}}>
<Rect x={size.value.width/2 - 50} width={100} height={100} color="lightblue" />
</Canvas>
日志确实产生了正确的值,但我的矩形仍然渲染不正确:
LOG Width: 312, Height: 200
我还尝试添加
mode="continuous"
,正如我预期的那样,在分配矩形的 x
值后,Skia 画布不会正确失效,但这也没有解决问题:
<Canvas onSize={size} onLayout={handleLayout} style={{height:200, margin:30, backgroundColor:"purple"}} mode="continuous">
<Rect x={size.value.width/2 - 50} width={100} height={100} color="lightblue" />
</Canvas>
在您第二次建议的尝试中,使用正常状态变量,它应该可以解决您的问题。
类似这样的事情
const [size, setSize] = useState<{ width: number, height: number }>({ width: 0, height: 0 })
而不是
const size = useSharedValue({ width: 0, height: 0 });
根据获取画布大小的画布文档。像常规 React Native 组件一样使用 onLayout。如果你想把它当作skia动画,还有onSize。