Reputation: 51
I want to create a simple app where I can choose between pencil, brush and eraser. I have Home.js and addLine.js. But there is a bug which I cant fix. When I change from brush back to pencil I'am drawing with the pencil but there is something like a border surrounding the pencil drawing which takes the color I previously used for the brush. Sample bug pucture If it matters I used react color for color picking.
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;
and addLine
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();
});
};
Upvotes: 0
Views: 1398
Reputation: 20288
On button click, you are calling addLine()
function:
<button onClick= { () => addLine(stageEl.current.getStage(), layerEl.current, color, "pencil")}>Pencil</button>
Inside that function you are adding NEW even listeners:
stage.on("mousedown touchstart", function(e) {
// .. function
});
That means a new listener is added on every click. So when you click on another tool, the old one will still work.
Two fix the issue you can use two ways:
Listen to the stage event just once, and inside addLine()
function just change the current attributes of current line. Similar to how it done in Konva free drawing demo
Or just remove all previous listeners inside addLine()
function with node.off() method. But I don't recommend that approach as it may lead to bugs if you remove wrong listeners.
Upvotes: 0