@tsdraw/core 0.8.3 → 0.8.4
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/index.cjs +104 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -19
- package/dist/index.d.ts +50 -19
- package/dist/index.js +102 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -260,6 +260,89 @@ function zoomViewport(viewport, factor, centerX, centerY) {
|
|
|
260
260
|
return { x, y, zoom };
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
// src/canvas/cameraPan.ts
|
|
264
|
+
var VELOCITY_LERP_FACTOR = 0.5;
|
|
265
|
+
var VELOCITY_ZERO_THRESHOLD = 0.01;
|
|
266
|
+
function beginCameraPan(viewport, screenX, screenY) {
|
|
267
|
+
return {
|
|
268
|
+
initialViewportX: viewport.x,
|
|
269
|
+
initialViewportY: viewport.y,
|
|
270
|
+
originScreenX: screenX,
|
|
271
|
+
originScreenY: screenY,
|
|
272
|
+
velocityX: 0,
|
|
273
|
+
velocityY: 0,
|
|
274
|
+
previousScreenX: screenX,
|
|
275
|
+
previousScreenY: screenY,
|
|
276
|
+
lastMoveTime: performance.now()
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function moveCameraPan(session, currentScreenX, currentScreenY) {
|
|
280
|
+
const now = performance.now();
|
|
281
|
+
const elapsed = now - session.lastMoveTime;
|
|
282
|
+
if (elapsed > 0) {
|
|
283
|
+
const moveDx = currentScreenX - session.previousScreenX;
|
|
284
|
+
const moveDy = currentScreenY - session.previousScreenY;
|
|
285
|
+
const moveLen = Math.hypot(moveDx, moveDy);
|
|
286
|
+
if (moveLen > 0) {
|
|
287
|
+
const dirX = moveDx / moveLen;
|
|
288
|
+
const dirY = moveDy / moveLen;
|
|
289
|
+
const speed = moveLen / elapsed;
|
|
290
|
+
session.velocityX += (dirX * speed - session.velocityX) * VELOCITY_LERP_FACTOR;
|
|
291
|
+
session.velocityY += (dirY * speed - session.velocityY) * VELOCITY_LERP_FACTOR;
|
|
292
|
+
}
|
|
293
|
+
if (Math.abs(session.velocityX) < VELOCITY_ZERO_THRESHOLD) session.velocityX = 0;
|
|
294
|
+
if (Math.abs(session.velocityY) < VELOCITY_ZERO_THRESHOLD) session.velocityY = 0;
|
|
295
|
+
}
|
|
296
|
+
session.previousScreenX = currentScreenX;
|
|
297
|
+
session.previousScreenY = currentScreenY;
|
|
298
|
+
session.lastMoveTime = now;
|
|
299
|
+
return {
|
|
300
|
+
x: session.initialViewportX + (currentScreenX - session.originScreenX),
|
|
301
|
+
y: session.initialViewportY + (currentScreenY - session.originScreenY)
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
var SLIDE_FRICTION = 0.92;
|
|
305
|
+
var SLIDE_MIN_SPEED = 0.01;
|
|
306
|
+
var SLIDE_MAX_SPEED = 2;
|
|
307
|
+
var SLIDE_MIN_VELOCITY_TO_START = 0.1;
|
|
308
|
+
function startCameraSlide(session, applyPan, onFrame) {
|
|
309
|
+
const timeSinceLastMove = performance.now() - session.lastMoveTime;
|
|
310
|
+
const FRAME_DURATION = 16;
|
|
311
|
+
const decayFactor = Math.pow(1 - VELOCITY_LERP_FACTOR, timeSinceLastMove / FRAME_DURATION);
|
|
312
|
+
const effectiveVx = session.velocityX * decayFactor;
|
|
313
|
+
const effectiveVy = session.velocityY * decayFactor;
|
|
314
|
+
const speed = Math.hypot(effectiveVx, effectiveVy);
|
|
315
|
+
const clampedSpeed = Math.min(speed, SLIDE_MAX_SPEED);
|
|
316
|
+
if (clampedSpeed < SLIDE_MIN_VELOCITY_TO_START) return null;
|
|
317
|
+
const dirX = effectiveVx / speed;
|
|
318
|
+
const dirY = effectiveVy / speed;
|
|
319
|
+
let currentSpeed = clampedSpeed;
|
|
320
|
+
let lastTime = performance.now();
|
|
321
|
+
let rafId = 0;
|
|
322
|
+
const tick = () => {
|
|
323
|
+
const now = performance.now();
|
|
324
|
+
const elapsed = now - lastTime;
|
|
325
|
+
lastTime = now;
|
|
326
|
+
applyPan(dirX * currentSpeed * elapsed, dirY * currentSpeed * elapsed);
|
|
327
|
+
onFrame();
|
|
328
|
+
currentSpeed *= SLIDE_FRICTION;
|
|
329
|
+
if (currentSpeed < SLIDE_MIN_SPEED) {
|
|
330
|
+
rafId = 0;
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
rafId = requestAnimationFrame(tick);
|
|
334
|
+
};
|
|
335
|
+
rafId = requestAnimationFrame(tick);
|
|
336
|
+
return {
|
|
337
|
+
stop() {
|
|
338
|
+
if (rafId !== 0) {
|
|
339
|
+
cancelAnimationFrame(rafId);
|
|
340
|
+
rafId = 0;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
263
346
|
// src/utils/colors.ts
|
|
264
347
|
var DARK_COLORS = {
|
|
265
348
|
black: "#f0f0f0",
|
|
@@ -1492,16 +1575,29 @@ var HandIdleState = class extends StateNode {
|
|
|
1492
1575
|
// src/tools/hand/states/HandDraggingState.ts
|
|
1493
1576
|
var HandDraggingState = class extends StateNode {
|
|
1494
1577
|
static id = "hand_dragging";
|
|
1578
|
+
panSession = null;
|
|
1579
|
+
onEnter(info) {
|
|
1580
|
+
const downInfo = info;
|
|
1581
|
+
const screenX = downInfo?.screenX ?? 0;
|
|
1582
|
+
const screenY = downInfo?.screenY ?? 0;
|
|
1583
|
+
this.panSession = beginCameraPan(this.editor.viewport, screenX, screenY);
|
|
1584
|
+
}
|
|
1495
1585
|
onPointerMove(info) {
|
|
1496
|
-
|
|
1497
|
-
const
|
|
1498
|
-
const
|
|
1499
|
-
|
|
1500
|
-
this.editor.
|
|
1586
|
+
if (!this.panSession) return;
|
|
1587
|
+
const screenX = info?.screenX ?? 0;
|
|
1588
|
+
const screenY = info?.screenY ?? 0;
|
|
1589
|
+
const target = moveCameraPan(this.panSession, screenX, screenY);
|
|
1590
|
+
this.editor.setViewport({ x: target.x, y: target.y });
|
|
1591
|
+
}
|
|
1592
|
+
getPanSession() {
|
|
1593
|
+
return this.panSession;
|
|
1501
1594
|
}
|
|
1502
1595
|
onPointerUp() {
|
|
1503
1596
|
this.ctx.transition("hand_idle");
|
|
1504
1597
|
}
|
|
1598
|
+
onExit() {
|
|
1599
|
+
this.panSession = null;
|
|
1600
|
+
}
|
|
1505
1601
|
onCancel() {
|
|
1506
1602
|
this.ctx.transition("hand_idle");
|
|
1507
1603
|
}
|
|
@@ -2186,6 +2282,7 @@ exports.ToolManager = ToolManager;
|
|
|
2186
2282
|
exports.applyMove = applyMove;
|
|
2187
2283
|
exports.applyResize = applyResize;
|
|
2188
2284
|
exports.applyRotation = applyRotation;
|
|
2285
|
+
exports.beginCameraPan = beginCameraPan;
|
|
2189
2286
|
exports.boundsContainPoint = boundsContainPoint;
|
|
2190
2287
|
exports.boundsIntersect = boundsIntersect;
|
|
2191
2288
|
exports.boundsOf = boundsOf;
|
|
@@ -2206,6 +2303,7 @@ exports.getShapesInBounds = getShapesInBounds;
|
|
|
2206
2303
|
exports.getTopShapeAtPoint = getTopShapeAtPoint;
|
|
2207
2304
|
exports.isSelectTool = isSelectTool;
|
|
2208
2305
|
exports.minDistanceToPolyline = minDistanceToPolyline;
|
|
2306
|
+
exports.moveCameraPan = moveCameraPan;
|
|
2209
2307
|
exports.normalizeSelectionBounds = normalizeSelectionBounds;
|
|
2210
2308
|
exports.padBounds = padBounds;
|
|
2211
2309
|
exports.pageToScreen = pageToScreen;
|
|
@@ -2220,6 +2318,7 @@ exports.segmentTouchesPolyline = segmentTouchesPolyline;
|
|
|
2220
2318
|
exports.setViewport = setViewport;
|
|
2221
2319
|
exports.shapePagePoints = shapePagePoints;
|
|
2222
2320
|
exports.sqDistance = sqDistance;
|
|
2321
|
+
exports.startCameraSlide = startCameraSlide;
|
|
2223
2322
|
exports.zoomViewport = zoomViewport;
|
|
2224
2323
|
//# sourceMappingURL=index.cjs.map
|
|
2225
2324
|
//# sourceMappingURL=index.cjs.map
|