react-native-canvas移动矩形留残影、75%画布区域失效问题求助
react-native-canvas拖动绘制残影、下半区域无法绘制问题修复
问题现象

黑色边框区域为完整Canvas画布范围,存在两个异常表现:
- 拖动矩形移动时,会留下无法清除的黑色残影痕迹
- 矩形向下移动到一定位置后会被隐藏,经测试约75%的Canvas画布区域无法正常工作
问题根因
- 未显式设置Canvas的
width/height绘制坐标系属性,仅通过flex设置布局样式,导致内部绘制坐标系和实际展示尺寸不匹配,下半区域绘制内容被截断 clearRect和fillRect参数错误:后两位参数为矩形宽高,原代码传入坐标值作为宽高,导致清除范围和绘制范围不匹配,残留残影- 上下文对象
ctx未做持久化存储,组件重渲染时会丢失引用;坐标更新后没有触发重绘逻辑,仅在Canvas初始化时绘制一次
修复后代码
import React, { useState, useRef, useEffect } from "react"; import { Text, View } from "react-native"; import Canvas from "react-native-canvas"; const App = () => { const [xAxis, setXAxis] = useState(100); const [yAxis, setYAxis] = useState(100); const [canvasSize, setCanvasSize] = useState({width: 0, height: 0}); const ctxRef = useRef(null); const canvasRef = useRef(null); // 坐标更新后重绘矩形 useEffect(() => { const ctx = ctxRef.current; if (!ctx || canvasSize.width === 0) return; // 清空整个画布避免残影 ctx.clearRect(0, 0, canvasSize.width, canvasSize.height); ctx.fillStyle = "blue"; // 绘制100*100的矩形,中心在(xAxis, yAxis) ctx.fillRect(xAxis - 50, yAxis - 50, 100, 100); }, [xAxis, yAxis, canvasSize]) const handleCanvas = (canvas) => { if (canvas) { canvasRef.current = canvas; ctxRef.current = canvas.getContext("2d"); } }; const onstart = (evt) => { setXAxis(evt.nativeEvent.locationX); setYAxis(evt.nativeEvent.locationY); }; const onmove = (evt) => { setXAxis(evt.nativeEvent.locationX); setYAxis(evt.nativeEvent.locationY); }; const onrelease = (evt) => { console.log("release", evt.nativeEvent.locationX); }; return ( <View onStartShouldSetResponder={() => true} onResponderStart={onstart} onResponderMove={onmove} onResponderRelease={onrelease} style={{ flex: 1, alignItems: "center", backgroundColor: "green" }} > <Text>Drawing Pad</Text> <Canvas ref={handleCanvas} onLayout={(e) => { const {width, height} = e.nativeEvent.layout; setCanvasSize({width, height}); // 显式设置canvas绘制坐标系尺寸 if (canvasRef.current) { canvasRef.current.width = width; canvasRef.current.height = height; } }} style={{ flex: 1, borderColor: "#000", borderWidth: 1, width: '100%' }} /> </View> ); }; export default App;
内容的提问来源于stack exchange,提问作者Vikas Acharya
相关产品推荐
相关产品推荐

