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

react-native-canvas移动矩形留残影、75%画布区域失效问题求助

react-native-canvas拖动绘制残影、下半区域无法绘制问题修复

问题现象

imgonline-com-ua-twotoone-438L58fyXL jpg-mh (1)
黑色边框区域为完整Canvas画布范围,存在两个异常表现:

  • 拖动矩形移动时,会留下无法清除的黑色残影痕迹
  • 矩形向下移动到一定位置后会被隐藏,经测试约75%的Canvas画布区域无法正常工作

问题根因

  1. 未显式设置Canvas的width/height绘制坐标系属性,仅通过flex设置布局样式,导致内部绘制坐标系和实际展示尺寸不匹配,下半区域绘制内容被截断
  2. clearRect和fillRect参数错误:后两位参数为矩形宽高,原代码传入坐标值作为宽高,导致清除范围和绘制范围不匹配,残留残影
  3. 上下文对象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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:54:01