Skip to content

Commit

Permalink
feat: Function image zooming in mobile clients
Browse files Browse the repository at this point in the history
  • Loading branch information
NriotHrreion committed May 25, 2024
1 parent 06cd42e commit 295487f
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 12 deletions.
58 changes: 48 additions & 10 deletions src/renderer/Render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export default class Render extends Graphics {
private mouseDY: number = 0; // mouse delta y
private cameraPosition: [number, number]; // [camera begin X, camera end X]

// Mobile zooming
private zoomingScale: number | null = null;
private lastZoomingSize: number | null = null;

private fpsUpdater: NodeJS.Timer;
private currentFPS: number = 0;
private lastTime: number = 0; // for FPS calculating
Expand Down Expand Up @@ -135,6 +139,8 @@ export default class Render extends Graphics {

public handleMouseUp() {
this.stopMoving();
this.zoomingScale = null;
this.lastZoomingSize = null;
}

public handleWheel(dy: number) {
Expand All @@ -144,16 +150,7 @@ export default class Render extends Graphics {
dy > 0
? this.scale -= delta / this.spacing
: this.scale += delta / this.spacing;

if(this.scale * this.spacing <= 66) {
this.spacing === 2
? this.spacing = 5
: this.spacing *= 2;
} else if(this.scale * this.spacing >= 138) {
this.spacing === 5
? this.spacing = 2
: this.spacing /= 2;
}
this.scalingAdapt();

this.zoomFunctionImage(dy > 0 ? ZoomDirection.ZOOM_OUT : ZoomDirection.ZOOM_IN);

Expand All @@ -165,6 +162,35 @@ export default class Render extends Graphics {
this.center.y -= centerDy * this.scale;
}

public handleTouchZoom(rect: DOMRect, cxA: number, cyA: number, cxB: number, cyB: number) {
cxA *= this.ratio;
cyA *= this.ratio;
cxB *= this.ratio;
cyB *= this.ratio;

const screenA = this.createPoint(cxA - rect.left, cyA - rect.top);
const screenB = this.createPoint(cxB - rect.left, cyB - rect.top);
const zoomingSize = Math.sqrt((screenA.x - screenB.x) ** 2 + (screenA.y - screenB.y) ** 2);

if(!this.lastZoomingSize) this.lastZoomingSize = zoomingSize;

if(!this.zoomingScale) {
this.zoomingScale = zoomingSize / this.scale;
return;
}

this.scale = zoomingSize / this.zoomingScale;
this.scalingAdapt();

this.zoomFunctionImage(
(this.lastZoomingSize && this.lastZoomingSize > zoomingSize)
? ZoomDirection.ZOOM_OUT
: ZoomDirection.ZOOM_IN
);

this.lastZoomingSize = zoomingSize;
}

private refreshMousePoint(rect: DOMRect, cx: number, cy: number) {
var mousePoint = this.createPoint(cx - rect.left, cy - rect.top);
this.mousePoint = mousePoint;
Expand Down Expand Up @@ -324,4 +350,16 @@ export default class Render extends Graphics {
this.displayedPoints.clear();
clearInterval(this.fpsUpdater);
}

public scalingAdapt() {
if(this.scale * this.spacing <= 66) {
this.spacing === 2
? this.spacing = 5
: this.spacing *= 2;
} else if(this.scale * this.spacing >= 138) {
this.spacing === 5
? this.spacing = 2
: this.spacing /= 2;
}
}
}
30 changes: 28 additions & 2 deletions src/views/graphing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,36 @@ const Graphing: React.FC = memo(() => {

// Init mobile events
var lastTouch: Touch;
canvas.addEventListener("touchstart", (e: TouchEvent) => {
var isTouchZooming = false;
canvas.addEventListener("touchstart", async (e: TouchEvent) => {
if(!workerRef.current) return;
workerRef.current.postMessage({ type: "mouse-down", rect: canvas.getBoundingClientRect(), cx: e.touches[0].clientX, cy: e.touches[0].clientY });

if(e.touches.length === 1) {
workerRef.current.postMessage({ type: "mouse-down", rect: canvas.getBoundingClientRect(), cx: e.touches[0].clientX, cy: e.touches[0].clientY });
} else if(!isTouchZooming && e.touches.length === 2) {
isTouchZooming = true;
}
});
canvas.addEventListener("touchmove", (e: TouchEvent) => {
if(!workerRef.current) return;

e.preventDefault();

if(isTouchZooming && e.touches.length === 2) {
const touchA = e.touches[0];
const touchB = e.touches[1];

workerRef.current.postMessage({
type: "touch-zoom",
rect: canvas.getBoundingClientRect(),
cxA: touchA.clientX,
cyA: touchA.clientY,
cxB: touchB.clientX,
cyB: touchB.clientY
});
return;
}

if(!lastTouch) lastTouch = e.changedTouches[0];

var direction: MovingDirection;
Expand All @@ -136,10 +158,14 @@ const Graphing: React.FC = memo(() => {
});
canvas.addEventListener("touchend", () => {
if(!workerRef.current) return;

isTouchZooming = false;
workerRef.current.postMessage({ type: "mouse-up" });
});
canvas.addEventListener("touchcancel", () => {
if(!workerRef.current) return;

isTouchZooming = false;
workerRef.current.postMessage({ type: "mouse-up" });
});

Expand Down
3 changes: 3 additions & 0 deletions src/workers/graphing.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ ctx.addEventListener("message", (e) => {
case "wheel":
renderer.handleWheel(req.dy);
break;
case "touch-zoom":
renderer.handleTouchZoom(req.rect, req.cxA, req.cyA, req.cxB, req.cyB);
break;
case "theme-change":
req.isDarkMode
? renderer.config.setTheme(Theme.DARK)
Expand Down

1 comment on commit 295487f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.