0

我想创建一个简单的应用程序,我可以在其中选择铅笔、画笔和橡皮擦。我有 Home.js 和 addLine.js。但是有一个我无法修复的错误。当我从画笔改回铅笔时,我正在用铅笔画画,但是铅笔画周围有一个边框,它采用了我之前用于画笔的颜色。错误图片示例如果重要,我使用反应颜色进行颜色选择。

const Home = () => {
 
  
  const stageEl = React.createRef();
  const layerEl = React.createRef();
  const [color, setColor] = useState('');

  
  return (
    <div className="home-page-div">
      <h1>This is the Home page!</h1>
    
      <button onClick= { () => addLine(stageEl.current.getStage(), layerEl.current, color, "pencil")}>Pencil</button>
     <button onClick={ () => addLine(stageEl.current.getStage(), layerEl.current, color, "brush")}>Brush</button>
      <button onClick={() => addLine(stageEl.current.getStage(), layerEl.current, color, "eraser")}>Erase</button>
      <CompactPicker 
      color={color} 
      onChange={(color)=>{setColor(color.hex)}}
      />       
      <Stage
        width={window.innerWidth * 0.9}
        height={window.innerHeight - 150}
        ref={stageEl}
      
      >
        <Layer ref={layerEl}>
        
        </Layer>
      </Stage>
    </div>
  )
};

export default Home;

和添加线

export const addLine = (stage, layer, color, mode) => {
  let isPaint = false;
  let lastLine;
 
  stage.on("mousedown touchstart", function(e) {
    isPaint = true;
    let pos = stage.getPointerPosition();
    lastLine = new Konva.Line({
      stroke:  `${color}`,
      strokeWidth:  mode === "brush" ? 8 : mode === "pencil" ? 1 : 10,
      globalCompositeOperation:
        mode === "eraser" ? 'destination-out' : 'source-over',
      points: [pos.x, pos.y],
      draggable: false,
    });
    layer.add(lastLine);
  });
  console.log(mode);
  console.log(color);
  stage.on("mouseup touchend", function() {
    isPaint = false;
  });
  stage.on("mousemove touchmove", function() {
    if (!isPaint) {
      return;
    }
    
  const pos = stage.getPointerPosition();
    let newPoints = lastLine.points().concat([pos.x, pos.y]);
    lastLine.points(newPoints);
    layer.batchDraw();
  });
};
   
4

1 回答 1

0

单击按钮时,您正在调用addLine()函数:

<button onClick= { () => addLine(stageEl.current.getStage(), layerEl.current, color, "pencil")}>Pencil</button>

在该函数中,您正在添加新的甚至监听器:

stage.on("mousedown touchstart", function(e) {
  // .. function
});

这意味着每次点击都会添加一个新的侦听器。因此,当您单击另一个工具时,旧工具仍然可以使用。

两个修复问题可以使用两种方法:

  1. 只需监听一次舞台事件,内部addLine()函数只需更改当前行的当前属性。类似于在Konva 免费绘图演示中的完成方式

  2. 或者只是使用node.off() 方法addLine()删除函数内所有以前的侦听器。但我不推荐这种方法,因为如果您删除错误的侦听器,它可能会导致错误。

于 2020-09-04T18:09:20.040 回答