@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.d.cts
CHANGED
|
@@ -149,8 +149,31 @@ declare class InputManager {
|
|
|
149
149
|
getInputs(): PointerInput;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
interface Viewport {
|
|
153
|
+
x: number;
|
|
154
|
+
y: number;
|
|
155
|
+
zoom: number;
|
|
156
|
+
}
|
|
157
|
+
declare function createViewport(): Viewport;
|
|
158
|
+
declare function screenToPage(viewport: Viewport, screenX: number, screenY: number): {
|
|
159
|
+
x: number;
|
|
160
|
+
y: number;
|
|
161
|
+
};
|
|
162
|
+
declare function pageToScreen(viewport: Viewport, pageX: number, pageY: number): {
|
|
163
|
+
x: number;
|
|
164
|
+
y: number;
|
|
165
|
+
};
|
|
166
|
+
declare function setViewport(viewport: Viewport, updater: {
|
|
167
|
+
x?: number;
|
|
168
|
+
y?: number;
|
|
169
|
+
zoom?: number;
|
|
170
|
+
}): Viewport;
|
|
171
|
+
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
172
|
+
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number): Viewport;
|
|
173
|
+
|
|
152
174
|
interface IEditor {
|
|
153
175
|
getZoomLevel(): number;
|
|
176
|
+
readonly viewport: Viewport;
|
|
154
177
|
options: {
|
|
155
178
|
dragDistanceSquared: number;
|
|
156
179
|
};
|
|
@@ -180,15 +203,20 @@ interface IEditor {
|
|
|
180
203
|
fill: FillStyle;
|
|
181
204
|
size: SizeStyle;
|
|
182
205
|
}>): void;
|
|
206
|
+
setViewport(partial: Partial<Viewport>): void;
|
|
183
207
|
panBy(dx: number, dy: number): void;
|
|
184
208
|
}
|
|
185
209
|
|
|
186
210
|
interface ToolPointerDownInfo {
|
|
187
211
|
point: Vec3;
|
|
212
|
+
screenX?: number;
|
|
213
|
+
screenY?: number;
|
|
188
214
|
}
|
|
189
215
|
interface ToolPointerMoveInfo {
|
|
190
216
|
screenDeltaX?: number;
|
|
191
217
|
screenDeltaY?: number;
|
|
218
|
+
screenX?: number;
|
|
219
|
+
screenY?: number;
|
|
192
220
|
}
|
|
193
221
|
interface ToolKeyInfo {
|
|
194
222
|
key: string;
|
|
@@ -217,27 +245,26 @@ declare abstract class StateNode {
|
|
|
217
245
|
onInterrupt(): void;
|
|
218
246
|
}
|
|
219
247
|
|
|
220
|
-
interface
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
248
|
+
interface CameraPanSession {
|
|
249
|
+
initialViewportX: number;
|
|
250
|
+
initialViewportY: number;
|
|
251
|
+
originScreenX: number;
|
|
252
|
+
originScreenY: number;
|
|
253
|
+
velocityX: number;
|
|
254
|
+
velocityY: number;
|
|
255
|
+
previousScreenX: number;
|
|
256
|
+
previousScreenY: number;
|
|
257
|
+
lastMoveTime: number;
|
|
258
|
+
}
|
|
259
|
+
declare function beginCameraPan(viewport: Viewport, screenX: number, screenY: number): CameraPanSession;
|
|
260
|
+
declare function moveCameraPan(session: CameraPanSession, currentScreenX: number, currentScreenY: number): {
|
|
227
261
|
x: number;
|
|
228
262
|
y: number;
|
|
229
263
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
declare function setViewport(viewport: Viewport, updater: {
|
|
235
|
-
x?: number;
|
|
236
|
-
y?: number;
|
|
237
|
-
zoom?: number;
|
|
238
|
-
}): Viewport;
|
|
239
|
-
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
240
|
-
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number): Viewport;
|
|
264
|
+
interface CameraSlideAnimation {
|
|
265
|
+
stop: () => void;
|
|
266
|
+
}
|
|
267
|
+
declare function startCameraSlide(session: CameraPanSession, applyPan: (dx: number, dy: number) => void, onFrame: () => void): CameraSlideAnimation | null;
|
|
241
268
|
|
|
242
269
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
243
270
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -608,8 +635,12 @@ declare class HandIdleState extends StateNode {
|
|
|
608
635
|
|
|
609
636
|
declare class HandDraggingState extends StateNode {
|
|
610
637
|
static id: string;
|
|
638
|
+
private panSession;
|
|
639
|
+
onEnter(info?: ToolStateTransitionInfo): void;
|
|
611
640
|
onPointerMove(info?: ToolPointerMoveInfo): void;
|
|
641
|
+
getPanSession(): CameraPanSession | null;
|
|
612
642
|
onPointerUp(): void;
|
|
643
|
+
onExit(): void;
|
|
613
644
|
onCancel(): void;
|
|
614
645
|
onInterrupt(): void;
|
|
615
646
|
}
|
|
@@ -625,4 +656,4 @@ declare function decodePathToPoints(segments: {
|
|
|
625
656
|
y: number;
|
|
626
657
|
}[];
|
|
627
658
|
|
|
628
|
-
export { type Bounds, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, type DashStyle, type DefaultToolId, DocumentStore, type DocumentStoreSnapshot, type DrawSegment, type DrawShape, ERASER_MARGIN, Editor, type EditorOptions, EraserErasingState, EraserIdleState, EraserPointingState, type FillStyle, HandDraggingState, HandIdleState, type ICanvasRenderer, type IEditor, InputManager, MAX_POINTS_PER_SHAPE, type PageState, PenDrawingState, PenIdleState, type PointerInput, type ResizeHandle, STROKE_WIDTHS, type SegmentType, SelectIdleState, type SelectionBounds, type Shape, type ShapeId, type SizeStyle, SquareDrawingState, SquareIdleState, StateNode, type StateNodeConstructor, type ToolDefinition, type ToolId, type ToolKeyInfo, ToolManager, type ToolPointerDownInfo, type ToolPointerMoveInfo, type ToolStateContext, type ToolStateTransitionInfo, type TransformSnapshot, type TsdrawDocumentSnapshot, type TsdrawEditorSnapshot, type TsdrawHistorySnapshot, type TsdrawPageRecord, type TsdrawPersistedRecord, type TsdrawRenderTheme, type TsdrawSessionStateSnapshot, type TsdrawShapeRecord, type Vec3, type Viewport, applyMove, applyResize, applyRotation, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, zoomViewport };
|
|
659
|
+
export { type Bounds, type CameraPanSession, type CameraSlideAnimation, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, type DashStyle, type DefaultToolId, DocumentStore, type DocumentStoreSnapshot, type DrawSegment, type DrawShape, ERASER_MARGIN, Editor, type EditorOptions, EraserErasingState, EraserIdleState, EraserPointingState, type FillStyle, HandDraggingState, HandIdleState, type ICanvasRenderer, type IEditor, InputManager, MAX_POINTS_PER_SHAPE, type PageState, PenDrawingState, PenIdleState, type PointerInput, type ResizeHandle, STROKE_WIDTHS, type SegmentType, SelectIdleState, type SelectionBounds, type Shape, type ShapeId, type SizeStyle, SquareDrawingState, SquareIdleState, StateNode, type StateNodeConstructor, type ToolDefinition, type ToolId, type ToolKeyInfo, ToolManager, type ToolPointerDownInfo, type ToolPointerMoveInfo, type ToolStateContext, type ToolStateTransitionInfo, type TransformSnapshot, type TsdrawDocumentSnapshot, type TsdrawEditorSnapshot, type TsdrawHistorySnapshot, type TsdrawPageRecord, type TsdrawPersistedRecord, type TsdrawRenderTheme, type TsdrawSessionStateSnapshot, type TsdrawShapeRecord, type Vec3, type Viewport, applyMove, applyResize, applyRotation, beginCameraPan, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, moveCameraPan, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, startCameraSlide, zoomViewport };
|
package/dist/index.d.ts
CHANGED
|
@@ -149,8 +149,31 @@ declare class InputManager {
|
|
|
149
149
|
getInputs(): PointerInput;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
interface Viewport {
|
|
153
|
+
x: number;
|
|
154
|
+
y: number;
|
|
155
|
+
zoom: number;
|
|
156
|
+
}
|
|
157
|
+
declare function createViewport(): Viewport;
|
|
158
|
+
declare function screenToPage(viewport: Viewport, screenX: number, screenY: number): {
|
|
159
|
+
x: number;
|
|
160
|
+
y: number;
|
|
161
|
+
};
|
|
162
|
+
declare function pageToScreen(viewport: Viewport, pageX: number, pageY: number): {
|
|
163
|
+
x: number;
|
|
164
|
+
y: number;
|
|
165
|
+
};
|
|
166
|
+
declare function setViewport(viewport: Viewport, updater: {
|
|
167
|
+
x?: number;
|
|
168
|
+
y?: number;
|
|
169
|
+
zoom?: number;
|
|
170
|
+
}): Viewport;
|
|
171
|
+
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
172
|
+
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number): Viewport;
|
|
173
|
+
|
|
152
174
|
interface IEditor {
|
|
153
175
|
getZoomLevel(): number;
|
|
176
|
+
readonly viewport: Viewport;
|
|
154
177
|
options: {
|
|
155
178
|
dragDistanceSquared: number;
|
|
156
179
|
};
|
|
@@ -180,15 +203,20 @@ interface IEditor {
|
|
|
180
203
|
fill: FillStyle;
|
|
181
204
|
size: SizeStyle;
|
|
182
205
|
}>): void;
|
|
206
|
+
setViewport(partial: Partial<Viewport>): void;
|
|
183
207
|
panBy(dx: number, dy: number): void;
|
|
184
208
|
}
|
|
185
209
|
|
|
186
210
|
interface ToolPointerDownInfo {
|
|
187
211
|
point: Vec3;
|
|
212
|
+
screenX?: number;
|
|
213
|
+
screenY?: number;
|
|
188
214
|
}
|
|
189
215
|
interface ToolPointerMoveInfo {
|
|
190
216
|
screenDeltaX?: number;
|
|
191
217
|
screenDeltaY?: number;
|
|
218
|
+
screenX?: number;
|
|
219
|
+
screenY?: number;
|
|
192
220
|
}
|
|
193
221
|
interface ToolKeyInfo {
|
|
194
222
|
key: string;
|
|
@@ -217,27 +245,26 @@ declare abstract class StateNode {
|
|
|
217
245
|
onInterrupt(): void;
|
|
218
246
|
}
|
|
219
247
|
|
|
220
|
-
interface
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
248
|
+
interface CameraPanSession {
|
|
249
|
+
initialViewportX: number;
|
|
250
|
+
initialViewportY: number;
|
|
251
|
+
originScreenX: number;
|
|
252
|
+
originScreenY: number;
|
|
253
|
+
velocityX: number;
|
|
254
|
+
velocityY: number;
|
|
255
|
+
previousScreenX: number;
|
|
256
|
+
previousScreenY: number;
|
|
257
|
+
lastMoveTime: number;
|
|
258
|
+
}
|
|
259
|
+
declare function beginCameraPan(viewport: Viewport, screenX: number, screenY: number): CameraPanSession;
|
|
260
|
+
declare function moveCameraPan(session: CameraPanSession, currentScreenX: number, currentScreenY: number): {
|
|
227
261
|
x: number;
|
|
228
262
|
y: number;
|
|
229
263
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
declare function setViewport(viewport: Viewport, updater: {
|
|
235
|
-
x?: number;
|
|
236
|
-
y?: number;
|
|
237
|
-
zoom?: number;
|
|
238
|
-
}): Viewport;
|
|
239
|
-
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
240
|
-
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number): Viewport;
|
|
264
|
+
interface CameraSlideAnimation {
|
|
265
|
+
stop: () => void;
|
|
266
|
+
}
|
|
267
|
+
declare function startCameraSlide(session: CameraPanSession, applyPan: (dx: number, dy: number) => void, onFrame: () => void): CameraSlideAnimation | null;
|
|
241
268
|
|
|
242
269
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
243
270
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -608,8 +635,12 @@ declare class HandIdleState extends StateNode {
|
|
|
608
635
|
|
|
609
636
|
declare class HandDraggingState extends StateNode {
|
|
610
637
|
static id: string;
|
|
638
|
+
private panSession;
|
|
639
|
+
onEnter(info?: ToolStateTransitionInfo): void;
|
|
611
640
|
onPointerMove(info?: ToolPointerMoveInfo): void;
|
|
641
|
+
getPanSession(): CameraPanSession | null;
|
|
612
642
|
onPointerUp(): void;
|
|
643
|
+
onExit(): void;
|
|
613
644
|
onCancel(): void;
|
|
614
645
|
onInterrupt(): void;
|
|
615
646
|
}
|
|
@@ -625,4 +656,4 @@ declare function decodePathToPoints(segments: {
|
|
|
625
656
|
y: number;
|
|
626
657
|
}[];
|
|
627
658
|
|
|
628
|
-
export { type Bounds, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, type DashStyle, type DefaultToolId, DocumentStore, type DocumentStoreSnapshot, type DrawSegment, type DrawShape, ERASER_MARGIN, Editor, type EditorOptions, EraserErasingState, EraserIdleState, EraserPointingState, type FillStyle, HandDraggingState, HandIdleState, type ICanvasRenderer, type IEditor, InputManager, MAX_POINTS_PER_SHAPE, type PageState, PenDrawingState, PenIdleState, type PointerInput, type ResizeHandle, STROKE_WIDTHS, type SegmentType, SelectIdleState, type SelectionBounds, type Shape, type ShapeId, type SizeStyle, SquareDrawingState, SquareIdleState, StateNode, type StateNodeConstructor, type ToolDefinition, type ToolId, type ToolKeyInfo, ToolManager, type ToolPointerDownInfo, type ToolPointerMoveInfo, type ToolStateContext, type ToolStateTransitionInfo, type TransformSnapshot, type TsdrawDocumentSnapshot, type TsdrawEditorSnapshot, type TsdrawHistorySnapshot, type TsdrawPageRecord, type TsdrawPersistedRecord, type TsdrawRenderTheme, type TsdrawSessionStateSnapshot, type TsdrawShapeRecord, type Vec3, type Viewport, applyMove, applyResize, applyRotation, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, zoomViewport };
|
|
659
|
+
export { type Bounds, type CameraPanSession, type CameraSlideAnimation, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, type DashStyle, type DefaultToolId, DocumentStore, type DocumentStoreSnapshot, type DrawSegment, type DrawShape, ERASER_MARGIN, Editor, type EditorOptions, EraserErasingState, EraserIdleState, EraserPointingState, type FillStyle, HandDraggingState, HandIdleState, type ICanvasRenderer, type IEditor, InputManager, MAX_POINTS_PER_SHAPE, type PageState, PenDrawingState, PenIdleState, type PointerInput, type ResizeHandle, STROKE_WIDTHS, type SegmentType, SelectIdleState, type SelectionBounds, type Shape, type ShapeId, type SizeStyle, SquareDrawingState, SquareIdleState, StateNode, type StateNodeConstructor, type ToolDefinition, type ToolId, type ToolKeyInfo, ToolManager, type ToolPointerDownInfo, type ToolPointerMoveInfo, type ToolStateContext, type ToolStateTransitionInfo, type TransformSnapshot, type TsdrawDocumentSnapshot, type TsdrawEditorSnapshot, type TsdrawHistorySnapshot, type TsdrawPageRecord, type TsdrawPersistedRecord, type TsdrawRenderTheme, type TsdrawSessionStateSnapshot, type TsdrawShapeRecord, type Vec3, type Viewport, applyMove, applyResize, applyRotation, beginCameraPan, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, moveCameraPan, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, startCameraSlide, zoomViewport };
|
package/dist/index.js
CHANGED
|
@@ -258,6 +258,89 @@ function zoomViewport(viewport, factor, centerX, centerY) {
|
|
|
258
258
|
return { x, y, zoom };
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
// src/canvas/cameraPan.ts
|
|
262
|
+
var VELOCITY_LERP_FACTOR = 0.5;
|
|
263
|
+
var VELOCITY_ZERO_THRESHOLD = 0.01;
|
|
264
|
+
function beginCameraPan(viewport, screenX, screenY) {
|
|
265
|
+
return {
|
|
266
|
+
initialViewportX: viewport.x,
|
|
267
|
+
initialViewportY: viewport.y,
|
|
268
|
+
originScreenX: screenX,
|
|
269
|
+
originScreenY: screenY,
|
|
270
|
+
velocityX: 0,
|
|
271
|
+
velocityY: 0,
|
|
272
|
+
previousScreenX: screenX,
|
|
273
|
+
previousScreenY: screenY,
|
|
274
|
+
lastMoveTime: performance.now()
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function moveCameraPan(session, currentScreenX, currentScreenY) {
|
|
278
|
+
const now = performance.now();
|
|
279
|
+
const elapsed = now - session.lastMoveTime;
|
|
280
|
+
if (elapsed > 0) {
|
|
281
|
+
const moveDx = currentScreenX - session.previousScreenX;
|
|
282
|
+
const moveDy = currentScreenY - session.previousScreenY;
|
|
283
|
+
const moveLen = Math.hypot(moveDx, moveDy);
|
|
284
|
+
if (moveLen > 0) {
|
|
285
|
+
const dirX = moveDx / moveLen;
|
|
286
|
+
const dirY = moveDy / moveLen;
|
|
287
|
+
const speed = moveLen / elapsed;
|
|
288
|
+
session.velocityX += (dirX * speed - session.velocityX) * VELOCITY_LERP_FACTOR;
|
|
289
|
+
session.velocityY += (dirY * speed - session.velocityY) * VELOCITY_LERP_FACTOR;
|
|
290
|
+
}
|
|
291
|
+
if (Math.abs(session.velocityX) < VELOCITY_ZERO_THRESHOLD) session.velocityX = 0;
|
|
292
|
+
if (Math.abs(session.velocityY) < VELOCITY_ZERO_THRESHOLD) session.velocityY = 0;
|
|
293
|
+
}
|
|
294
|
+
session.previousScreenX = currentScreenX;
|
|
295
|
+
session.previousScreenY = currentScreenY;
|
|
296
|
+
session.lastMoveTime = now;
|
|
297
|
+
return {
|
|
298
|
+
x: session.initialViewportX + (currentScreenX - session.originScreenX),
|
|
299
|
+
y: session.initialViewportY + (currentScreenY - session.originScreenY)
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
var SLIDE_FRICTION = 0.92;
|
|
303
|
+
var SLIDE_MIN_SPEED = 0.01;
|
|
304
|
+
var SLIDE_MAX_SPEED = 2;
|
|
305
|
+
var SLIDE_MIN_VELOCITY_TO_START = 0.1;
|
|
306
|
+
function startCameraSlide(session, applyPan, onFrame) {
|
|
307
|
+
const timeSinceLastMove = performance.now() - session.lastMoveTime;
|
|
308
|
+
const FRAME_DURATION = 16;
|
|
309
|
+
const decayFactor = Math.pow(1 - VELOCITY_LERP_FACTOR, timeSinceLastMove / FRAME_DURATION);
|
|
310
|
+
const effectiveVx = session.velocityX * decayFactor;
|
|
311
|
+
const effectiveVy = session.velocityY * decayFactor;
|
|
312
|
+
const speed = Math.hypot(effectiveVx, effectiveVy);
|
|
313
|
+
const clampedSpeed = Math.min(speed, SLIDE_MAX_SPEED);
|
|
314
|
+
if (clampedSpeed < SLIDE_MIN_VELOCITY_TO_START) return null;
|
|
315
|
+
const dirX = effectiveVx / speed;
|
|
316
|
+
const dirY = effectiveVy / speed;
|
|
317
|
+
let currentSpeed = clampedSpeed;
|
|
318
|
+
let lastTime = performance.now();
|
|
319
|
+
let rafId = 0;
|
|
320
|
+
const tick = () => {
|
|
321
|
+
const now = performance.now();
|
|
322
|
+
const elapsed = now - lastTime;
|
|
323
|
+
lastTime = now;
|
|
324
|
+
applyPan(dirX * currentSpeed * elapsed, dirY * currentSpeed * elapsed);
|
|
325
|
+
onFrame();
|
|
326
|
+
currentSpeed *= SLIDE_FRICTION;
|
|
327
|
+
if (currentSpeed < SLIDE_MIN_SPEED) {
|
|
328
|
+
rafId = 0;
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
rafId = requestAnimationFrame(tick);
|
|
332
|
+
};
|
|
333
|
+
rafId = requestAnimationFrame(tick);
|
|
334
|
+
return {
|
|
335
|
+
stop() {
|
|
336
|
+
if (rafId !== 0) {
|
|
337
|
+
cancelAnimationFrame(rafId);
|
|
338
|
+
rafId = 0;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
261
344
|
// src/utils/colors.ts
|
|
262
345
|
var DARK_COLORS = {
|
|
263
346
|
black: "#f0f0f0",
|
|
@@ -1490,16 +1573,29 @@ var HandIdleState = class extends StateNode {
|
|
|
1490
1573
|
// src/tools/hand/states/HandDraggingState.ts
|
|
1491
1574
|
var HandDraggingState = class extends StateNode {
|
|
1492
1575
|
static id = "hand_dragging";
|
|
1576
|
+
panSession = null;
|
|
1577
|
+
onEnter(info) {
|
|
1578
|
+
const downInfo = info;
|
|
1579
|
+
const screenX = downInfo?.screenX ?? 0;
|
|
1580
|
+
const screenY = downInfo?.screenY ?? 0;
|
|
1581
|
+
this.panSession = beginCameraPan(this.editor.viewport, screenX, screenY);
|
|
1582
|
+
}
|
|
1493
1583
|
onPointerMove(info) {
|
|
1494
|
-
|
|
1495
|
-
const
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
this.editor.
|
|
1584
|
+
if (!this.panSession) return;
|
|
1585
|
+
const screenX = info?.screenX ?? 0;
|
|
1586
|
+
const screenY = info?.screenY ?? 0;
|
|
1587
|
+
const target = moveCameraPan(this.panSession, screenX, screenY);
|
|
1588
|
+
this.editor.setViewport({ x: target.x, y: target.y });
|
|
1589
|
+
}
|
|
1590
|
+
getPanSession() {
|
|
1591
|
+
return this.panSession;
|
|
1499
1592
|
}
|
|
1500
1593
|
onPointerUp() {
|
|
1501
1594
|
this.ctx.transition("hand_idle");
|
|
1502
1595
|
}
|
|
1596
|
+
onExit() {
|
|
1597
|
+
this.panSession = null;
|
|
1598
|
+
}
|
|
1503
1599
|
onCancel() {
|
|
1504
1600
|
this.ctx.transition("hand_idle");
|
|
1505
1601
|
}
|
|
@@ -2158,6 +2254,6 @@ function applyResize(editor, handle, startBounds, startShapes, pointer, lockAspe
|
|
|
2158
2254
|
}
|
|
2159
2255
|
}
|
|
2160
2256
|
|
|
2161
|
-
export { CanvasRenderer, CircleDrawingState, CircleIdleState, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, DocumentStore, ERASER_MARGIN, Editor, EraserErasingState, EraserIdleState, EraserPointingState, HandDraggingState, HandIdleState, InputManager, MAX_POINTS_PER_SHAPE, PenDrawingState, PenIdleState, STROKE_WIDTHS, SelectIdleState, SquareDrawingState, SquareIdleState, StateNode, ToolManager, applyMove, applyResize, applyRotation, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds2 as getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, zoomViewport };
|
|
2257
|
+
export { CanvasRenderer, CircleDrawingState, CircleIdleState, DEFAULT_COLORS, DRAG_DISTANCE_SQUARED, DocumentStore, ERASER_MARGIN, Editor, EraserErasingState, EraserIdleState, EraserPointingState, HandDraggingState, HandIdleState, InputManager, MAX_POINTS_PER_SHAPE, PenDrawingState, PenIdleState, STROKE_WIDTHS, SelectIdleState, SquareDrawingState, SquareIdleState, StateNode, ToolManager, applyMove, applyResize, applyRotation, beginCameraPan, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, closestOnSegment, createViewport, decodeFirstPoint, decodeLastPoint, decodePathToPoints, decodePoints, distance, documentSnapshotToRecords, encodePoints, getSelectionBoundsPage, getShapeBounds2 as getShapeBounds, getShapesInBounds, getTopShapeAtPoint, isSelectTool, minDistanceToPolyline, moveCameraPan, normalizeSelectionBounds, padBounds, pageToScreen, panViewport, pointHitsShape, recordsToDocumentSnapshot, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, startCameraSlide, zoomViewport };
|
|
2162
2258
|
//# sourceMappingURL=index.js.map
|
|
2163
2259
|
//# sourceMappingURL=index.js.map
|