вот ваша проблема:
const startPosition = (e) => {
setIsPainting(true);
drawCanvas(e);
};
вы запускаете обновление состояния setIsPainting
, а затем сразу запускаете drawCanvas
, которое ретранслирует состояние рисования. и реагировать на состояние обновления асинхронно, поэтому при drawCanvas
fire:
const drawCanvas = (e) => {
if (!isPainting) return;
ctx.lineWidth = 10;
ctx.lineCap = "round";
ctx.strokeStyle = "red";
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(e.clientX, e.clientY);
console.log('drawing')
};
isPainting
будет ложным, поэтому функция вернется.
для решения этой проблемы попробуйте добавить запуск drawCanavs в useEffect
hook или componentDidUpdate
для класса Component, например:
useEffect(()=>{
drawCanvas(startPosition)
,[isPainting]}
этот эффект сработает, когда isPainting
изменение состояния + вам нужно добавить дополнительное состояние для сохранения startPosition или события щелчка.
отредактировано: окончательный код:
const MyCanavas = ()=>{
canvasRef = useRef();
const [isPainting,setIsPainting] = useState({painting:false,startPostion:null})
const startPosition = (e) => {
const event = e
setIsPainting({painting:true,startPostion:event});
};
const drawCanvas = (e) => {
if (!isPainting.painting) return;
const ctx = canvasRef.current.getContext("2d");
ctx.lineWidth = 10;
ctx.lineCap = "round";
ctx.strokeStyle = "red";
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(e.clientX, e.clientY);
console.log('drawing')
};
// Finished position of drawing
const finishedPosition = () => {
const ctx = canvasRef.current.getContext("2d");
setIsPainting({painting:false,startPostion:null});
ctx.beginPath();
};
useEffect(()=>{
const canvas = canvasRef.current
canvas.addEventListener("mousedown", (e) => {
startPosition(e);
});
canvas.addEventListener("mouseup", () => {
finishedPosition();
});
canvas.addEventListener("mousemove", (e) => {
drawCanvas(e);
});
return ()=>{
canvas.removeEventListener("mousedown")
canvas.removeEventListener("mouseup")
canvas.removeEventListener("mousemove") // clean up
}
},[])
useEffect(()=>{
drawCanvas(isPainting.startPosition)
},[isPainting]
return <Canvas ref={canvasRef}/>
}