停止 canvas 线宽变化时的清除
Stop canvas clearing on lineWidth change
我有一个 React 应用程序,可让您绘制 select 不同的线宽。
代码:
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 改变整个 canvas 不会重新渲染,只有线宽会。现在它可以工作但是如果我 select 一个新的 lineWidth 整个 canvas 被清除。
我建议您不要以这种方式使用 eventListener,ReactJS
中的 canvas 已经有一些您可以访问和传递函数的方法。这种处理 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功能解决方案
我有一个 React 应用程序,可让您绘制 select 不同的线宽。
代码:
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 改变整个 canvas 不会重新渲染,只有线宽会。现在它可以工作但是如果我 select 一个新的 lineWidth 整个 canvas 被清除。
我建议您不要以这种方式使用 eventListener,ReactJS
中的 canvas 已经有一些您可以访问和传递函数的方法。这种处理 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功能解决方案