canvas 反应问题 - 错误计算鼠标位置
React problem with canvas - misscalculate position of mouse
我尝试使用 typescript + styled-components + react 在浏览器中构建迷你绘图,但是 Canvas 在我尝试绘制某些东西时错误地计算了鼠标的位置。事情是,只有当我使用位于 CanvasContainer 内的 canvas 时,它才会发生,如果我只是在 ImageEditor 内写入标签 ,那么位置就会被正确计算。有谁知道为什么会发生以及如何解决?因为我真的不明白这种行为。
export default function ImageEditorContainer() {
const CANVAS_REF = useRef<any>(null);
const isDrawing = useRef(false);
function startDrawing(event: MouseEvent) {
isDrawing.current = true;
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('STARt');
context.beginPath();
context.moveTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
event.preventDefault();
}
function draw(event: MouseEvent) {
if (isDrawing.current) {
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('Draw');
context.lineTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
context.strokeStyle = 'black';
context.lineWidth = '3px';
context.lineCap = 'round';
context.lineJoin = 'round';
context.stroke();
}
event.preventDefault();
}
function stopDrawing(event: MouseEvent) {
if (isDrawing.current) {
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('STOP');
context.stroke();
context.closePath();
isDrawing.current = false;
}
event.preventDefault();
}
useEffect(() => {
const canvas = CANVAS_REF.current;
if (canvas) {
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
}
}, []);
return (
<>
....
<CanvasContainer CANVAS_REF={CANVAS_REF} ... />
</>
);
}
export default function CanvasContainer({ ...restProps }: TCanvasContent) {
return (
<Canvas.Container>
<Canvas.Content {...restProps} />
</Canvas.Container>
);
}
export default function Canvas({ children }: TCanvas) {
return { children };
}
Canvas.Content = function CanvasContent({ CANVAS_REF, ...restProps }: TCanvasContent) {
return <Content ref={CANVAS_REF} {...restProps} />;
};
https://codesandbox.io/s/dank-dust-vo4lh?file=/src/CanvasContainer.js
成功了。
https://codesandbox.io/s/peaceful-jepsen-wh913?file=/src/App.js
canvas 的“样式”错误。
我尝试使用 typescript + styled-components + react 在浏览器中构建迷你绘图,但是 Canvas 在我尝试绘制某些东西时错误地计算了鼠标的位置。事情是,只有当我使用位于 CanvasContainer 内的 canvas 时,它才会发生,如果我只是在 ImageEditor 内写入标签 ,那么位置就会被正确计算。有谁知道为什么会发生以及如何解决?因为我真的不明白这种行为。
export default function ImageEditorContainer() {
const CANVAS_REF = useRef<any>(null);
const isDrawing = useRef(false);
function startDrawing(event: MouseEvent) {
isDrawing.current = true;
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('STARt');
context.beginPath();
context.moveTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
event.preventDefault();
}
function draw(event: MouseEvent) {
if (isDrawing.current) {
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('Draw');
context.lineTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
context.strokeStyle = 'black';
context.lineWidth = '3px';
context.lineCap = 'round';
context.lineJoin = 'round';
context.stroke();
}
event.preventDefault();
}
function stopDrawing(event: MouseEvent) {
if (isDrawing.current) {
const canvas = CANVAS_REF.current;
const context = canvas.getContext('2d');
console.log('STOP');
context.stroke();
context.closePath();
isDrawing.current = false;
}
event.preventDefault();
}
useEffect(() => {
const canvas = CANVAS_REF.current;
if (canvas) {
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
}
}, []);
return (
<>
....
<CanvasContainer CANVAS_REF={CANVAS_REF} ... />
</>
);
}
export default function CanvasContainer({ ...restProps }: TCanvasContent) {
return (
<Canvas.Container>
<Canvas.Content {...restProps} />
</Canvas.Container>
);
}
export default function Canvas({ children }: TCanvas) {
return { children };
}
Canvas.Content = function CanvasContent({ CANVAS_REF, ...restProps }: TCanvasContent) {
return <Content ref={CANVAS_REF} {...restProps} />;
};
https://codesandbox.io/s/dank-dust-vo4lh?file=/src/CanvasContainer.js
成功了。
https://codesandbox.io/s/peaceful-jepsen-wh913?file=/src/App.js
canvas 的“样式”错误。