Skip to content

Commit e92ac7c

Browse files
committed
Refactor demo code
1 parent 3ad7fbd commit e92ac7c

10 files changed

Lines changed: 896 additions & 848 deletions

File tree

Src/FastData.Demo/wwwroot/algorithms/common.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ function buildUniformValues(size, start, step) {
3737
}
3838

3939
export function createRng(seed) {
40-
let state = (seed >>> 0) || 1;
40+
let state = seed >>> 0 || 1;
4141

4242
return () => {
43-
state = (state * 1664525 + 1013904223) >>> 0;
43+
state = state * 1664525 + 1013904223 >>> 0;
4444
return state / 4294967296;
4545
};
4646
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import { MAX_ZOOM, MIN_ZOOM } from "./preferences.js";
2+
3+
function clamp(value, min, max) {
4+
return Math.max(min, Math.min(max, value));
5+
}
6+
7+
export class CameraController {
8+
constructor(options) {
9+
this.getActiveCamera = options.getActiveCamera;
10+
this.onCameraChanged = options.onCameraChanged;
11+
this.canvas = null;
12+
this.dragging = false;
13+
this.lastPointer = null;
14+
}
15+
16+
attachCanvas(canvas) {
17+
this.canvas = canvas;
18+
19+
this.canvas.addEventListener("wheel", event => this.onWheel(event), { passive: false });
20+
this.canvas.addEventListener("pointerdown", event => this.onPointerDown(event));
21+
this.canvas.addEventListener("pointermove", event => this.onPointerMove(event));
22+
this.canvas.addEventListener("pointerup", event => this.onPointerUp(event));
23+
this.canvas.addEventListener("pointercancel", event => this.onPointerUp(event));
24+
this.canvas.addEventListener("dblclick", event => {
25+
event.preventDefault();
26+
this.resetView();
27+
});
28+
}
29+
30+
onWheel(event) {
31+
if (!this.canvas) {
32+
return;
33+
}
34+
35+
event.preventDefault();
36+
const pointer = this.getPointerPosition(event);
37+
if (!pointer) {
38+
return;
39+
}
40+
41+
const factor = event.deltaY < 0 ? 1.1 : 1 / 1.1;
42+
this.zoomAt(pointer.x, pointer.y, factor);
43+
this.onCameraChanged();
44+
}
45+
46+
onPointerDown(event) {
47+
if (!this.canvas || event.button !== 0) {
48+
return;
49+
}
50+
51+
const pointer = this.getPointerPosition(event);
52+
if (!pointer) {
53+
return;
54+
}
55+
56+
this.dragging = true;
57+
this.lastPointer = pointer;
58+
this.canvas.classList.add("is-panning");
59+
this.canvas.setPointerCapture(event.pointerId);
60+
event.preventDefault();
61+
}
62+
63+
onPointerMove(event) {
64+
if (!this.canvas || !this.dragging) {
65+
return;
66+
}
67+
68+
const pointer = this.getPointerPosition(event);
69+
if (!pointer || !this.lastPointer) {
70+
return;
71+
}
72+
73+
const dx = pointer.x - this.lastPointer.x;
74+
const dy = pointer.y - this.lastPointer.y;
75+
this.lastPointer = pointer;
76+
this.panBy(dx, dy);
77+
event.preventDefault();
78+
}
79+
80+
onPointerUp(event) {
81+
if (!this.canvas) {
82+
return;
83+
}
84+
85+
this.dragging = false;
86+
this.lastPointer = null;
87+
this.canvas.classList.remove("is-panning");
88+
this.onCameraChanged();
89+
90+
if (this.canvas.hasPointerCapture(event.pointerId)) {
91+
this.canvas.releasePointerCapture(event.pointerId);
92+
}
93+
}
94+
95+
getPointerPosition(event) {
96+
if (!this.canvas) {
97+
return null;
98+
}
99+
100+
const rect = this.canvas.getBoundingClientRect();
101+
return {
102+
x: event.clientX - rect.left,
103+
y: event.clientY - rect.top
104+
};
105+
}
106+
107+
zoomAt(screenX, screenY, factor) {
108+
if (factor === 0) {
109+
return;
110+
}
111+
112+
const camera = this.getActiveCamera();
113+
const oldZoom = camera.zoom;
114+
const newZoom = clamp(oldZoom * factor, MIN_ZOOM, MAX_ZOOM);
115+
116+
if (newZoom === oldZoom) {
117+
return;
118+
}
119+
120+
const worldX = (screenX - camera.panX) / oldZoom;
121+
const worldY = (screenY - camera.panY) / oldZoom;
122+
123+
camera.zoom = newZoom;
124+
camera.panX = screenX - worldX * newZoom;
125+
camera.panY = screenY - worldY * newZoom;
126+
}
127+
128+
panBy(dx, dy) {
129+
const camera = this.getActiveCamera();
130+
camera.panX += dx;
131+
camera.panY += dy;
132+
}
133+
134+
resetView() {
135+
const camera = this.getActiveCamera();
136+
camera.zoom = 1;
137+
camera.panX = 0;
138+
camera.panY = 0;
139+
this.onCameraChanged();
140+
}
141+
}

0 commit comments

Comments
 (0)