aifastdb-devplan 1.5.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autopilot.d.ts +58 -0
- package/dist/autopilot.d.ts.map +1 -0
- package/dist/autopilot.js +250 -0
- package/dist/autopilot.js.map +1 -0
- package/dist/dev-plan-document-store.d.ts +15 -1
- package/dist/dev-plan-document-store.d.ts.map +1 -1
- package/dist/dev-plan-document-store.js +122 -0
- package/dist/dev-plan-document-store.js.map +1 -1
- package/dist/dev-plan-factory.d.ts +69 -3
- package/dist/dev-plan-factory.d.ts.map +1 -1
- package/dist/dev-plan-factory.js +113 -19
- package/dist/dev-plan-factory.js.map +1 -1
- package/dist/dev-plan-graph-store.d.ts +79 -1
- package/dist/dev-plan-graph-store.d.ts.map +1 -1
- package/dist/dev-plan-graph-store.js +420 -3
- package/dist/dev-plan-graph-store.js.map +1 -1
- package/dist/dev-plan-interface.d.ts +24 -1
- package/dist/dev-plan-interface.d.ts.map +1 -1
- package/dist/dev-plan-migrate.d.ts +1 -0
- package/dist/dev-plan-migrate.d.ts.map +1 -1
- package/dist/dev-plan-migrate.js +28 -2
- package/dist/dev-plan-migrate.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/index.js +397 -4
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/types.d.ts +160 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -1
- package/dist/types.js.map +1 -1
- package/dist/visualize/graph-canvas/api-compat.d.ts +20 -0
- package/dist/visualize/graph-canvas/api-compat.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/api-compat.js +344 -0
- package/dist/visualize/graph-canvas/api-compat.js.map +1 -0
- package/dist/visualize/graph-canvas/clusterer.d.ts +16 -0
- package/dist/visualize/graph-canvas/clusterer.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/clusterer.js +460 -0
- package/dist/visualize/graph-canvas/clusterer.js.map +1 -0
- package/dist/visualize/graph-canvas/core.d.ts +11 -0
- package/dist/visualize/graph-canvas/core.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/core.js +1136 -0
- package/dist/visualize/graph-canvas/core.js.map +1 -0
- package/dist/visualize/graph-canvas/index.d.ts +22 -0
- package/dist/visualize/graph-canvas/index.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/index.js +69 -0
- package/dist/visualize/graph-canvas/index.js.map +1 -0
- package/dist/visualize/graph-canvas/interaction.d.ts +13 -0
- package/dist/visualize/graph-canvas/interaction.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/interaction.js +457 -0
- package/dist/visualize/graph-canvas/interaction.js.map +1 -0
- package/dist/visualize/graph-canvas/layout-worker.d.ts +17 -0
- package/dist/visualize/graph-canvas/layout-worker.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/layout-worker.js +577 -0
- package/dist/visualize/graph-canvas/layout-worker.js.map +1 -0
- package/dist/visualize/graph-canvas/lod.d.ts +10 -0
- package/dist/visualize/graph-canvas/lod.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/lod.js +111 -0
- package/dist/visualize/graph-canvas/lod.js.map +1 -0
- package/dist/visualize/graph-canvas/renderer.d.ts +12 -0
- package/dist/visualize/graph-canvas/renderer.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/renderer.js +813 -0
- package/dist/visualize/graph-canvas/renderer.js.map +1 -0
- package/dist/visualize/graph-canvas/spatial-index.d.ts +13 -0
- package/dist/visualize/graph-canvas/spatial-index.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/spatial-index.js +482 -0
- package/dist/visualize/graph-canvas/spatial-index.js.map +1 -0
- package/dist/visualize/graph-canvas/styles.d.ts +11 -0
- package/dist/visualize/graph-canvas/styles.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/styles.js +152 -0
- package/dist/visualize/graph-canvas/styles.js.map +1 -0
- package/dist/visualize/graph-canvas/viewport.d.ts +17 -0
- package/dist/visualize/graph-canvas/viewport.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/viewport.js +385 -0
- package/dist/visualize/graph-canvas/viewport.js.map +1 -0
- package/dist/visualize/server.js +737 -7
- package/dist/visualize/server.js.map +1 -1
- package/dist/visualize/template-core.d.ts +9 -0
- package/dist/visualize/template-core.d.ts.map +1 -0
- package/dist/visualize/template-core.js +714 -0
- package/dist/visualize/template-core.js.map +1 -0
- package/dist/visualize/template-data-loading.d.ts +7 -0
- package/dist/visualize/template-data-loading.d.ts.map +1 -0
- package/dist/visualize/template-data-loading.js +677 -0
- package/dist/visualize/template-data-loading.js.map +1 -0
- package/dist/visualize/template-detail-panel.d.ts +14 -0
- package/dist/visualize/template-detail-panel.d.ts.map +1 -0
- package/dist/visualize/template-detail-panel.js +553 -0
- package/dist/visualize/template-detail-panel.js.map +1 -0
- package/dist/visualize/template-graph-3d.d.ts +7 -0
- package/dist/visualize/template-graph-3d.d.ts.map +1 -0
- package/dist/visualize/template-graph-3d.js +1112 -0
- package/dist/visualize/template-graph-3d.js.map +1 -0
- package/dist/visualize/template-graph-vis.d.ts +8 -0
- package/dist/visualize/template-graph-vis.d.ts.map +1 -0
- package/dist/visualize/template-graph-vis.js +1204 -0
- package/dist/visualize/template-graph-vis.js.map +1 -0
- package/dist/visualize/template-html.d.ts +9 -0
- package/dist/visualize/template-html.d.ts.map +1 -0
- package/dist/visualize/template-html.js +484 -0
- package/dist/visualize/template-html.js.map +1 -0
- package/dist/visualize/template-pages.d.ts +7 -0
- package/dist/visualize/template-pages.d.ts.map +1 -0
- package/dist/visualize/template-pages.js +806 -0
- package/dist/visualize/template-pages.js.map +1 -0
- package/dist/visualize/template-stats-modal.d.ts +7 -0
- package/dist/visualize/template-stats-modal.d.ts.map +1 -0
- package/dist/visualize/template-stats-modal.js +406 -0
- package/dist/visualize/template-stats-modal.js.map +1 -0
- package/dist/visualize/template-styles.d.ts +9 -0
- package/dist/visualize/template-styles.d.ts.map +1 -0
- package/dist/visualize/template-styles.js +487 -0
- package/dist/visualize/template-styles.js.map +1 -0
- package/dist/visualize/template.d.ts +14 -3
- package/dist/visualize/template.d.ts.map +1 -1
- package/dist/visualize/template.js +38 -2889
- package/dist/visualize/template.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewport.d.ts","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/viewport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,wBAAgB,iBAAiB,IAAI,MAAM,CA6W1C"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ViewportManager — 平移/缩放/手势 + 世界↔屏幕坐标变换
|
|
4
|
+
*
|
|
5
|
+
* 管理 2D 视口变换矩阵:
|
|
6
|
+
* screenX = worldX * scale + offsetX
|
|
7
|
+
* screenY = worldY * scale + offsetY
|
|
8
|
+
*
|
|
9
|
+
* 支持:
|
|
10
|
+
* - 鼠标拖拽平移
|
|
11
|
+
* - 滚轮缩放 (以鼠标位置为中心)
|
|
12
|
+
* - 触摸双指缩放
|
|
13
|
+
* - fit() 自适应视口
|
|
14
|
+
* - zoomTo() 定位到特定坐标
|
|
15
|
+
* - 惯性平移 (inertia)
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.getViewportScript = getViewportScript;
|
|
19
|
+
function getViewportScript() {
|
|
20
|
+
return `
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// ViewportManager
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* ViewportManager — 管理世界到屏幕的坐标变换
|
|
27
|
+
* @param {GraphCanvas} engine - 父引擎实例
|
|
28
|
+
*/
|
|
29
|
+
function ViewportManager(engine) {
|
|
30
|
+
this._engine = engine;
|
|
31
|
+
|
|
32
|
+
// Transform state
|
|
33
|
+
this._offsetX = 0; // 屏幕平移 X (pixels)
|
|
34
|
+
this._offsetY = 0; // 屏幕平移 Y (pixels)
|
|
35
|
+
this._scale = 1; // 缩放比例 (1 = 100%)
|
|
36
|
+
|
|
37
|
+
// Constraints
|
|
38
|
+
this._minScale = 0.001; // 支持百万级节点需要极小缩放
|
|
39
|
+
this._maxScale = 20;
|
|
40
|
+
this._zoomSpeed = 0.001; // 滚轮灵敏度
|
|
41
|
+
|
|
42
|
+
// Drag state
|
|
43
|
+
this._isDragging = false;
|
|
44
|
+
this._dragStartX = 0;
|
|
45
|
+
this._dragStartY = 0;
|
|
46
|
+
this._dragOffsetStartX = 0;
|
|
47
|
+
this._dragOffsetStartY = 0;
|
|
48
|
+
|
|
49
|
+
// Inertia
|
|
50
|
+
this._velocityX = 0;
|
|
51
|
+
this._velocityY = 0;
|
|
52
|
+
this._lastDragTime = 0;
|
|
53
|
+
this._inertiaRafId = null;
|
|
54
|
+
|
|
55
|
+
// Touch zoom state
|
|
56
|
+
this._touchStartDist = 0;
|
|
57
|
+
this._touchStartScale = 1;
|
|
58
|
+
this._touchStartMidX = 0;
|
|
59
|
+
this._touchStartMidY = 0;
|
|
60
|
+
|
|
61
|
+
// Animation
|
|
62
|
+
this._animationRafId = null;
|
|
63
|
+
|
|
64
|
+
// Bind event handlers
|
|
65
|
+
this._bindEvents();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ── Coordinate Transforms ─────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert world coordinates to screen coordinates.
|
|
72
|
+
*/
|
|
73
|
+
ViewportManager.prototype.worldToScreen = function(wx, wy) {
|
|
74
|
+
return {
|
|
75
|
+
x: wx * this._scale + this._offsetX,
|
|
76
|
+
y: wy * this._scale + this._offsetY,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Convert screen coordinates to world coordinates.
|
|
82
|
+
*/
|
|
83
|
+
ViewportManager.prototype.screenToWorld = function(sx, sy) {
|
|
84
|
+
return {
|
|
85
|
+
x: (sx - this._offsetX) / this._scale,
|
|
86
|
+
y: (sy - this._offsetY) / this._scale,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get current world-space bounds visible in the viewport.
|
|
92
|
+
*/
|
|
93
|
+
ViewportManager.prototype.getWorldBounds = function() {
|
|
94
|
+
var w = this._engine._width;
|
|
95
|
+
var h = this._engine._height;
|
|
96
|
+
var tl = this.screenToWorld(0, 0);
|
|
97
|
+
var br = this.screenToWorld(w, h);
|
|
98
|
+
return {
|
|
99
|
+
minX: Math.min(tl.x, br.x),
|
|
100
|
+
minY: Math.min(tl.y, br.y),
|
|
101
|
+
maxX: Math.max(tl.x, br.x),
|
|
102
|
+
maxY: Math.max(tl.y, br.y),
|
|
103
|
+
width: Math.abs(br.x - tl.x),
|
|
104
|
+
height: Math.abs(br.y - tl.y),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// ── Apply Transform to Canvas Context ─────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Apply the current viewport transform to a Canvas2D context.
|
|
112
|
+
*/
|
|
113
|
+
ViewportManager.prototype.applyTransform = function(ctx) {
|
|
114
|
+
ctx.setTransform(
|
|
115
|
+
this._scale * this._engine._options.pixelRatio,
|
|
116
|
+
0, 0,
|
|
117
|
+
this._scale * this._engine._options.pixelRatio,
|
|
118
|
+
this._offsetX * this._engine._options.pixelRatio,
|
|
119
|
+
this._offsetY * this._engine._options.pixelRatio
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Reset transform to screen space (for UI overlays).
|
|
125
|
+
*/
|
|
126
|
+
ViewportManager.prototype.resetTransform = function(ctx) {
|
|
127
|
+
var pr = this._engine._options.pixelRatio;
|
|
128
|
+
ctx.setTransform(pr, 0, 0, pr, 0, 0);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// ── Viewport Operations ───────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Pan the viewport by screen-space delta.
|
|
135
|
+
*/
|
|
136
|
+
ViewportManager.prototype.pan = function(dx, dy) {
|
|
137
|
+
this._offsetX += dx;
|
|
138
|
+
this._offsetY += dy;
|
|
139
|
+
this._engine.markDirty();
|
|
140
|
+
this._engine._emit('viewportChanged', this._getState());
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Zoom centered on a screen-space point.
|
|
145
|
+
* @param {number} factor - Zoom multiplier (>1 = zoom in, <1 = zoom out)
|
|
146
|
+
* @param {number} centerX - Screen X to zoom around
|
|
147
|
+
* @param {number} centerY - Screen Y to zoom around
|
|
148
|
+
*/
|
|
149
|
+
ViewportManager.prototype.zoom = function(factor, centerX, centerY) {
|
|
150
|
+
var newScale = this._scale * factor;
|
|
151
|
+
newScale = Math.max(this._minScale, Math.min(newScale, this._maxScale));
|
|
152
|
+
|
|
153
|
+
// Zoom around center point:
|
|
154
|
+
// The world point under the center should stay in the same screen position
|
|
155
|
+
var worldBefore = this.screenToWorld(centerX, centerY);
|
|
156
|
+
this._scale = newScale;
|
|
157
|
+
var screenAfter = this.worldToScreen(worldBefore.x, worldBefore.y);
|
|
158
|
+
this._offsetX += centerX - screenAfter.x;
|
|
159
|
+
this._offsetY += centerY - screenAfter.y;
|
|
160
|
+
|
|
161
|
+
this._engine.markDirty();
|
|
162
|
+
this._engine._emit('viewportChanged', this._getState());
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Set absolute zoom level.
|
|
167
|
+
*/
|
|
168
|
+
ViewportManager.prototype.setScale = function(scale) {
|
|
169
|
+
var cx = this._engine._width / 2;
|
|
170
|
+
var cy = this._engine._height / 2;
|
|
171
|
+
this.zoom(scale / this._scale, cx, cy);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Fit viewport to show all given nodes.
|
|
176
|
+
* @param {Array} nodes - Array of {x, y, _radius} objects
|
|
177
|
+
* @param {Object} [options] - { padding, animation }
|
|
178
|
+
*/
|
|
179
|
+
ViewportManager.prototype.fitToNodes = function(nodes, options) {
|
|
180
|
+
if (!nodes || nodes.length === 0) return;
|
|
181
|
+
|
|
182
|
+
var opts = options || {};
|
|
183
|
+
var padding = opts.padding || 60;
|
|
184
|
+
|
|
185
|
+
// Compute bounding box of all nodes
|
|
186
|
+
var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
187
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
188
|
+
var n = nodes[i];
|
|
189
|
+
var r = n._radius || 10;
|
|
190
|
+
if (n.x - r < minX) minX = n.x - r;
|
|
191
|
+
if (n.y - r < minY) minY = n.y - r;
|
|
192
|
+
if (n.x + r > maxX) maxX = n.x + r;
|
|
193
|
+
if (n.y + r > maxY) maxY = n.y + r;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var bw = maxX - minX;
|
|
197
|
+
var bh = maxY - minY;
|
|
198
|
+
if (bw < 1) bw = 1;
|
|
199
|
+
if (bh < 1) bh = 1;
|
|
200
|
+
|
|
201
|
+
var w = this._engine._width - padding * 2;
|
|
202
|
+
var h = this._engine._height - padding * 2;
|
|
203
|
+
if (w < 1) w = 1;
|
|
204
|
+
if (h < 1) h = 1;
|
|
205
|
+
|
|
206
|
+
var scale = Math.min(w / bw, h / bh);
|
|
207
|
+
scale = Math.max(this._minScale, Math.min(scale, this._maxScale));
|
|
208
|
+
|
|
209
|
+
var centerX = (minX + maxX) / 2;
|
|
210
|
+
var centerY = (minY + maxY) / 2;
|
|
211
|
+
|
|
212
|
+
var targetOffsetX = this._engine._width / 2 - centerX * scale;
|
|
213
|
+
var targetOffsetY = this._engine._height / 2 - centerY * scale;
|
|
214
|
+
|
|
215
|
+
if (opts.animation !== false && opts.animation) {
|
|
216
|
+
this._animateTo(scale, targetOffsetX, targetOffsetY, opts.animation);
|
|
217
|
+
} else {
|
|
218
|
+
this._scale = scale;
|
|
219
|
+
this._offsetX = targetOffsetX;
|
|
220
|
+
this._offsetY = targetOffsetY;
|
|
221
|
+
this._engine.markDirty();
|
|
222
|
+
this._engine._emit('viewportChanged', this._getState());
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Center the view on a world coordinate.
|
|
228
|
+
*/
|
|
229
|
+
ViewportManager.prototype.centerOn = function(worldX, worldY, options) {
|
|
230
|
+
var targetOffsetX = this._engine._width / 2 - worldX * this._scale;
|
|
231
|
+
var targetOffsetY = this._engine._height / 2 - worldY * this._scale;
|
|
232
|
+
|
|
233
|
+
var opts = options || {};
|
|
234
|
+
if (opts.animation) {
|
|
235
|
+
this._animateTo(opts.scale || this._scale, targetOffsetX, targetOffsetY, opts.animation);
|
|
236
|
+
} else {
|
|
237
|
+
this._offsetX = targetOffsetX;
|
|
238
|
+
this._offsetY = targetOffsetY;
|
|
239
|
+
if (opts.scale) this._scale = opts.scale;
|
|
240
|
+
this._engine.markDirty();
|
|
241
|
+
this._engine._emit('viewportChanged', this._getState());
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// ── Animation ─────────────────────────────────────────────────────────────
|
|
246
|
+
|
|
247
|
+
ViewportManager.prototype._animateTo = function(targetScale, targetOffsetX, targetOffsetY, animOptions) {
|
|
248
|
+
if (this._animationRafId) cancelAnimationFrame(this._animationRafId);
|
|
249
|
+
|
|
250
|
+
var duration = (typeof animOptions === 'object' && animOptions.duration) || 800;
|
|
251
|
+
var startScale = this._scale;
|
|
252
|
+
var startOffsetX = this._offsetX;
|
|
253
|
+
var startOffsetY = this._offsetY;
|
|
254
|
+
var startTime = performance.now();
|
|
255
|
+
var self = this;
|
|
256
|
+
|
|
257
|
+
function easeInOutCubic(t) {
|
|
258
|
+
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function step(now) {
|
|
262
|
+
var t = Math.min((now - startTime) / duration, 1);
|
|
263
|
+
var e = easeInOutCubic(t);
|
|
264
|
+
|
|
265
|
+
self._scale = startScale + (targetScale - startScale) * e;
|
|
266
|
+
self._offsetX = startOffsetX + (targetOffsetX - startOffsetX) * e;
|
|
267
|
+
self._offsetY = startOffsetY + (targetOffsetY - startOffsetY) * e;
|
|
268
|
+
self._engine.markDirty();
|
|
269
|
+
|
|
270
|
+
if (t < 1) {
|
|
271
|
+
self._animationRafId = requestAnimationFrame(step);
|
|
272
|
+
} else {
|
|
273
|
+
self._animationRafId = null;
|
|
274
|
+
self._engine._emit('viewportChanged', self._getState());
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
this._animationRafId = requestAnimationFrame(step);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// ── Inertia (drag momentum) ──────────────────────────────────────────────
|
|
282
|
+
|
|
283
|
+
ViewportManager.prototype._startInertia = function() {
|
|
284
|
+
if (Math.abs(this._velocityX) < 0.5 && Math.abs(this._velocityY) < 0.5) return;
|
|
285
|
+
if (this._inertiaRafId) cancelAnimationFrame(this._inertiaRafId);
|
|
286
|
+
|
|
287
|
+
var self = this;
|
|
288
|
+
var friction = 0.95;
|
|
289
|
+
|
|
290
|
+
function step() {
|
|
291
|
+
self._velocityX *= friction;
|
|
292
|
+
self._velocityY *= friction;
|
|
293
|
+
if (Math.abs(self._velocityX) < 0.1 && Math.abs(self._velocityY) < 0.1) {
|
|
294
|
+
self._inertiaRafId = null;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
self.pan(self._velocityX, self._velocityY);
|
|
298
|
+
self._inertiaRafId = requestAnimationFrame(step);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
this._inertiaRafId = requestAnimationFrame(step);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// ── Event Binding ─────────────────────────────────────────────────────────
|
|
305
|
+
|
|
306
|
+
ViewportManager.prototype._bindEvents = function() {
|
|
307
|
+
var self = this;
|
|
308
|
+
var canvas = this._engine._canvas;
|
|
309
|
+
|
|
310
|
+
// ── Mouse Wheel → Zoom ──
|
|
311
|
+
canvas.addEventListener('wheel', function(e) {
|
|
312
|
+
e.preventDefault();
|
|
313
|
+
var rect = canvas.getBoundingClientRect();
|
|
314
|
+
var x = e.clientX - rect.left;
|
|
315
|
+
var y = e.clientY - rect.top;
|
|
316
|
+
var delta = -e.deltaY;
|
|
317
|
+
var factor = 1 + delta * self._zoomSpeed;
|
|
318
|
+
factor = Math.max(0.5, Math.min(factor, 2)); // clamp per-event
|
|
319
|
+
|
|
320
|
+
// T11.8: Flag zooming state to skip edge rendering during rapid zoom
|
|
321
|
+
var engine = self._engine;
|
|
322
|
+
engine._isZooming = true;
|
|
323
|
+
if (engine._zoomTimer) clearTimeout(engine._zoomTimer);
|
|
324
|
+
engine._zoomTimer = setTimeout(function() {
|
|
325
|
+
engine._isZooming = false;
|
|
326
|
+
engine.markDirty(); // Redraw with edges after zoom stops
|
|
327
|
+
}, 150);
|
|
328
|
+
|
|
329
|
+
self.zoom(factor, x, y);
|
|
330
|
+
}, { passive: false });
|
|
331
|
+
|
|
332
|
+
// ── Mouse drag → Pan (delegated to InteractionManager for node drag priority) ──
|
|
333
|
+
// Pan events are handled by InteractionManager which calls viewport.pan()
|
|
334
|
+
// when dragging on empty space.
|
|
335
|
+
|
|
336
|
+
// ── Touch events → Pan/Zoom ──
|
|
337
|
+
canvas.addEventListener('touchstart', function(e) {
|
|
338
|
+
if (e.touches.length === 2) {
|
|
339
|
+
e.preventDefault();
|
|
340
|
+
var t0 = e.touches[0], t1 = e.touches[1];
|
|
341
|
+
self._touchStartDist = Math.hypot(t1.clientX - t0.clientX, t1.clientY - t0.clientY);
|
|
342
|
+
self._touchStartScale = self._scale;
|
|
343
|
+
var rect = canvas.getBoundingClientRect();
|
|
344
|
+
self._touchStartMidX = ((t0.clientX + t1.clientX) / 2) - rect.left;
|
|
345
|
+
self._touchStartMidY = ((t0.clientY + t1.clientY) / 2) - rect.top;
|
|
346
|
+
}
|
|
347
|
+
}, { passive: false });
|
|
348
|
+
|
|
349
|
+
canvas.addEventListener('touchmove', function(e) {
|
|
350
|
+
if (e.touches.length === 2) {
|
|
351
|
+
e.preventDefault();
|
|
352
|
+
var t0 = e.touches[0], t1 = e.touches[1];
|
|
353
|
+
var dist = Math.hypot(t1.clientX - t0.clientX, t1.clientY - t0.clientY);
|
|
354
|
+
if (self._touchStartDist > 0) {
|
|
355
|
+
var factor = dist / self._touchStartDist;
|
|
356
|
+
var newScale = self._touchStartScale * factor;
|
|
357
|
+
newScale = Math.max(self._minScale, Math.min(newScale, self._maxScale));
|
|
358
|
+
var zoomFactor = newScale / self._scale;
|
|
359
|
+
self.zoom(zoomFactor, self._touchStartMidX, self._touchStartMidY);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}, { passive: false });
|
|
363
|
+
|
|
364
|
+
canvas.addEventListener('touchend', function(e) {
|
|
365
|
+
self._touchStartDist = 0;
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// ── State ─────────────────────────────────────────────────────────────────
|
|
370
|
+
|
|
371
|
+
ViewportManager.prototype._getState = function() {
|
|
372
|
+
return {
|
|
373
|
+
scale: this._scale,
|
|
374
|
+
offsetX: this._offsetX,
|
|
375
|
+
offsetY: this._offsetY,
|
|
376
|
+
worldBounds: this.getWorldBounds(),
|
|
377
|
+
};
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
ViewportManager.prototype.getScale = function() {
|
|
381
|
+
return this._scale;
|
|
382
|
+
};
|
|
383
|
+
`;
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=viewport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewport.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/viewport.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AAEH,8CA6WC;AA7WD,SAAgB,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2WR,CAAC;AACF,CAAC"}
|