【问题标题】:Stop canvas clearing on lineWidth change停止在线宽更改清除Canvas
【发布时间】:2021-07-12 11:45:06
【问题描述】:

我有一个 react 应用,可以让你绘制和选择不同的线宽。

代码:

const [sliderVal, setSliderVal] = useState(1) 
const canvasRef = useRef(null)
useEffect(() => {
    const canvas = canvasRef.current
    const ctx = canvas.getContext('2d')

    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;


    /* Mouse Capturing Work */
    var mouse = {x: 0, y: 0};
    var last_mouse = {x: 0, y: 0};

    canvas.addEventListener('mousemove', function(e) {
        last_mouse.x = mouse.x;
        last_mouse.y = mouse.y;

        mouse.x = e.pageX - this.offsetLeft;
        mouse.y = e.pageY - this.offsetTop;

        canvas.style.cursor = "crosshair";
    }, false);


    /* Drawing on Paint App */
    ctx.lineWidth = sliderVal;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.strokeStyle = 'blue';

    canvas.addEventListener('mousedown', function() {
        canvas.addEventListener('mousemove', onPaint, false);
    }, false);

    canvas.addEventListener('mouseup', function() {
        canvas.removeEventListener('mousemove', onPaint, false);
    }, false);

    var onPaint = function() {
        ctx.beginPath();
        ctx.moveTo(last_mouse.x, last_mouse.y);
        ctx.lineTo(mouse.x, mouse.y);
        ctx.closePath();
        ctx.stroke();
    };
}, [sliderVal])

我正在努力做到这一点,所以如果 sliderVal 改变了整个画布,则不会重新渲染只有线宽。现在它可以工作了,但是如果我选择一个新的 lineWidth,整个画布就会被清除。

【问题讨论】:

  • 您可以在画布上添加您绘制的部分吗?或代码框
  • 刚刚编辑过。

标签: reactjs html5-canvas


【解决方案1】:

我建议您不要以这种方式使用 eventListener,ReactJS 中的画布已经有一些您可以访问和传递函数的方法。这种处理canvas 的新方法可以解决您的问题:

  const [sliderVal, setSliderVal] = useState(1);
  const [mouse, setMouse] = useState({
    x: 0,
    y: 0,
    lastX: 0,
    lastY: 0,
    click: false
  });
  const canvasRef = useRef(null);

  const paint = (e) => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    const bounds = canvas.getBoundingClientRect();
    setMouse({
      ...mouse,
      x: e.pageX - bounds.left - window.scrollX,
      y: e.pageY - bounds.top - window.scrollY,
      lastX: mouse.x,
      lastY: mouse.y
    });
    ctx.lineWidth = sliderVal;
    ctx.lineJoin = "round";
    ctx.lineCap = "round";
    ctx.strokeStyle = "blue";
    if (mouse.click) {
      ctx.beginPath();
      ctx.moveTo(mouse.lastX, mouse.lastY);
      ctx.lineTo(mouse.x, mouse.y);
      ctx.closePath();
      ctx.stroke();
    }
  };
  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
    canvas.style.cursor = "crosshair";
  }, []);
  return (
      <canvas
        onMouseDown={() => setMouse({ ...mouse, click: true })}
        onMouseMove={(e) => paint(e)}
        onMouseUp={() => setMouse({ ...mouse, click: false })}
        ref={canvasRef}
      />

我与功能解决方案分享codesandbox

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多