Fix signature canvas: preventDefault on touch events, scale coords to canvas pixels

This commit is contained in:
Dave 2026-08-17 22:03:07 +02:00
parent 620a2373bb
commit ca697a3b19
2 changed files with 21 additions and 9 deletions

View file

@ -42,28 +42,37 @@ export default function SignPage() {
const getPos = (e: React.MouseEvent | React.TouchEvent) => {
const canvas = canvasRef.current!;
const rect = canvas.getBoundingClientRect();
// Scale from display CSS pixels to canvas internal pixels
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
if ("touches" in e) {
return {
x: e.touches[0].clientX - rect.left,
y: e.touches[0].clientY - rect.top,
x: (e.touches[0].clientX - rect.left) * scaleX,
y: (e.touches[0].clientY - rect.top) * scaleY,
};
}
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
return {
x: (e.clientX - rect.left) * scaleX,
y: (e.clientY - rect.top) * scaleY,
};
};
const startDraw = (e: React.MouseEvent | React.TouchEvent) => {
e.preventDefault();
drawing.current = true;
lastPos.current = getPos(e);
};
const draw = (e: React.MouseEvent | React.TouchEvent) => {
if (!drawing.current) return;
e.preventDefault();
const canvas = canvasRef.current!;
const ctx = canvas.getContext("2d")!;
const pos = getPos(e);
ctx.strokeStyle = "#1a1a2e";
ctx.lineWidth = 2.5;
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
ctx.moveTo(lastPos.current.x, lastPos.current.y);
ctx.lineTo(pos.x, pos.y);
@ -71,7 +80,10 @@ export default function SignPage() {
lastPos.current = pos;
};
const stopDraw = () => { drawing.current = false; };
const stopDraw = (e?: React.MouseEvent | React.TouchEvent) => {
if (e) e.preventDefault();
drawing.current = false;
};
const clearCanvas = () => {
const canvas = canvasRef.current!;
@ -165,9 +177,9 @@ export default function SignPage() {
<canvas
ref={canvasRef}
width={560}
height={180}
className="w-full cursor-crosshair touch-none"
style={{ height: 180, display: "block" }}
height={200}
className="w-full cursor-crosshair touch-none select-none"
style={{ height: 200, display: "block" }}
onMouseDown={startDraw}
onMouseMove={draw}
onMouseUp={stopDraw}

File diff suppressed because one or more lines are too long