Skip to content

Commit

Permalink
feat: improve mobile UX
Browse files Browse the repository at this point in the history
  • Loading branch information
DerStimmler committed Sep 29, 2024
1 parent 58fd5fb commit d95ad26
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 39 deletions.
51 changes: 23 additions & 28 deletions src/routes/Canvas.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
let initialRotation = 0;
let initialMidpoint = { x: 0, y: 0 };
let initialPosition = { x: 0, y: 0 };
let isTouching = false;
// Set the offset to the center of the image to rotate around center
image.offsetX(image.width() / 2);
Expand All @@ -128,31 +129,27 @@
image.on('touchstart', function (e) {
const touches = e.evt.touches;
// Prevent default behavior for touch events
e.evt.preventDefault();
// Single-finger drag (move the image)
if (touches.length === 1) {
const touch = touches[0];
initialPosition = { x: touch.clientX, y: touch.clientY };
isTouching = true;
}
// Multi-touch gesture (scale and rotate)
if (touches.length === 2) {
e.evt.preventDefault();
const touch1 = touches[0];
const touch2 = touches[1];
const p1 = {
x: touch1.clientX,
y: touch1.clientY
};
const p2 = {
x: touch2.clientX,
y: touch2.clientY
};
const p1 = { x: touch1.clientX, y: touch1.clientY };
const p2 = { x: touch2.clientX, y: touch2.clientY };
initialDistance = getDistance(p1, p2);
initialAngle = getAngle(p1, p2);
initialScale = image.scaleX(); // assume uniform scaling (scaleX == scaleY)
initialScale = image.scaleX(); // assume uniform scaling
initialRotation = image.rotation();
initialMidpoint = getCenter(p1, p2);
initialPosition = { x: image.x(), y: image.y() }; // store image's initial position
Expand All @@ -162,37 +159,32 @@
image.on('touchmove', function (e) {
const touches = e.evt.touches;
// Prevent default behavior for touch events
e.evt.preventDefault();
// Single-finger drag logic
if (touches.length === 1) {
if (isTouching && touches.length === 1) {
const touch = touches[0];
// Calculate new position based on touch movement
const dx = touch.clientX - initialPosition.x;
const dy = touch.clientY - initialPosition.y;
image.x(image.x() + dx);
image.y(image.y() + dy);
// Update initial position to the current one
initialPosition = { x: touch.clientX, y: touch.clientY };
image.position({
x: initialPosition.x + dx,
y: initialPosition.y + dy
});
image.getLayer()?.batchDraw();
}
// Multi-touch gesture (scale and rotate)
if (touches.length === 2) {
e.evt.preventDefault();
const touch1 = touches[0];
const touch2 = touches[1];
const p1 = {
x: touch1.clientX,
y: touch1.clientY
};
const p2 = {
x: touch2.clientX,
y: touch2.clientY
};
const p1 = { x: touch1.clientX, y: touch1.clientY };
const p2 = { x: touch2.clientX, y: touch2.clientY };
const newDistance = getDistance(p1, p2);
const newAngle = getAngle(p1, p2);
Expand All @@ -202,8 +194,10 @@
const dx = newMidpoint.x - initialMidpoint.x;
const dy = newMidpoint.y - initialMidpoint.y;
image.x(initialPosition.x + dx);
image.y(initialPosition.y + dy);
image.position({
x: initialPosition.x + dx,
y: initialPosition.y + dy
});
// Calculate the scaling factor
const scaleFactor = newDistance / initialDistance;
Expand All @@ -228,6 +222,7 @@
initialDistance = 0;
initialAngle = 0;
initialMidpoint = { x: 0, y: 0 };
isTouching = false;
}
});
}
Expand Down
25 changes: 14 additions & 11 deletions src/routes/SignatureDraw.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,28 @@
return { offsetX: 0, offsetY: 0 };
}
function startDrawing(event: MouseEvent | TouchEvent) {
function startDrawing(event: PointerEvent) {
if (event.cancelable) event.preventDefault();
isDrawing = true;
const { offsetX, offsetY } = getOffset(event);
ctx.beginPath();
ctx.moveTo(offsetX, offsetY);
}
function draw(event: MouseEvent | TouchEvent) {
function draw(event: PointerEvent) {
if (event.cancelable) event.preventDefault();
if (!isDrawing) return;
const { offsetX, offsetY } = getOffset(event);
ctx.lineTo(offsetX, offsetY);
ctx.stroke();
}
function stopDrawing(event: MouseEvent | TouchEvent) {
function stopDrawing(event: PointerEvent) {
if (event.cancelable) event.preventDefault();
isDrawing = false;
close(canvas!.toDataURL()!);
}
Expand All @@ -76,14 +82,11 @@
bind:this={canvas}
width="0"
height="150"
class="bg-white border-border border rounded-md"
onmousedown={startDrawing}
onmousemove={draw}
onmouseup={stopDrawing}
onmouseleave={stopDrawing}
ontouchstart={startDrawing}
ontouchmove={draw}
ontouchend={stopDrawing}
class="bg-white border-border border rounded-md touch-none"
onpointerdown={startDrawing}
onpointermove={draw}
onpointerup={stopDrawing}
onpointercancel={stopDrawing}
>
</canvas>
</div>
Expand Down

0 comments on commit d95ad26

Please sign in to comment.