如何在 React Native 和 Skia (react-native-skia) 中将画布中的矩形居中?

问题描述 投票:0回答:1

总结

我想使用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>
react-native layout react-native-skia
1个回答
0
投票

在您第二次建议的尝试中,使用正常状态变量,它应该可以解决您的问题。

类似这样的事情

const [size, setSize] = useState<{ width: number, height: number }>({ width: 0, height: 0 })

而不是

const size = useSharedValue({ width: 0, height: 0 });

根据获取画布大小的画布文档。像常规 React Native 组件一样使用 onLayout。如果你想把它当作skia动画,还有onSize。

© www.soinside.com 2019 - 2024. All rights reserved.