@tsdraw/core 0.8.3 → 0.8.5
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 +117 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -19
- package/dist/index.d.ts +61 -19
- package/dist/index.js +113 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -149,8 +149,37 @@ 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
|
+
interface ZoomRange {
|
|
173
|
+
min: number;
|
|
174
|
+
max: number;
|
|
175
|
+
}
|
|
176
|
+
declare const DEFAULT_ZOOM_RANGE: ZoomRange;
|
|
177
|
+
declare function clampZoom(zoom: number, range?: ZoomRange): number;
|
|
178
|
+
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number, zoomRange?: ZoomRange): Viewport;
|
|
179
|
+
|
|
152
180
|
interface IEditor {
|
|
153
181
|
getZoomLevel(): number;
|
|
182
|
+
readonly viewport: Viewport;
|
|
154
183
|
options: {
|
|
155
184
|
dragDistanceSquared: number;
|
|
156
185
|
};
|
|
@@ -180,15 +209,20 @@ interface IEditor {
|
|
|
180
209
|
fill: FillStyle;
|
|
181
210
|
size: SizeStyle;
|
|
182
211
|
}>): void;
|
|
212
|
+
setViewport(partial: Partial<Viewport>): void;
|
|
183
213
|
panBy(dx: number, dy: number): void;
|
|
184
214
|
}
|
|
185
215
|
|
|
186
216
|
interface ToolPointerDownInfo {
|
|
187
217
|
point: Vec3;
|
|
218
|
+
screenX?: number;
|
|
219
|
+
screenY?: number;
|
|
188
220
|
}
|
|
189
221
|
interface ToolPointerMoveInfo {
|
|
190
222
|
screenDeltaX?: number;
|
|
191
223
|
screenDeltaY?: number;
|
|
224
|
+
screenX?: number;
|
|
225
|
+
screenY?: number;
|
|
192
226
|
}
|
|
193
227
|
interface ToolKeyInfo {
|
|
194
228
|
key: string;
|
|
@@ -217,27 +251,29 @@ declare abstract class StateNode {
|
|
|
217
251
|
onInterrupt(): void;
|
|
218
252
|
}
|
|
219
253
|
|
|
220
|
-
interface
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
254
|
+
interface CameraPanSession {
|
|
255
|
+
initialViewportX: number;
|
|
256
|
+
initialViewportY: number;
|
|
257
|
+
originScreenX: number;
|
|
258
|
+
originScreenY: number;
|
|
259
|
+
velocityX: number;
|
|
260
|
+
velocityY: number;
|
|
261
|
+
previousScreenX: number;
|
|
262
|
+
previousScreenY: number;
|
|
263
|
+
lastMoveTime: number;
|
|
264
|
+
}
|
|
265
|
+
declare function beginCameraPan(viewport: Viewport, screenX: number, screenY: number): CameraPanSession;
|
|
266
|
+
declare function moveCameraPan(session: CameraPanSession, currentScreenX: number, currentScreenY: number): {
|
|
227
267
|
x: number;
|
|
228
268
|
y: number;
|
|
229
269
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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;
|
|
270
|
+
interface CameraSlideAnimation {
|
|
271
|
+
stop: () => void;
|
|
272
|
+
}
|
|
273
|
+
interface CameraSlideOptions {
|
|
274
|
+
friction?: number;
|
|
275
|
+
}
|
|
276
|
+
declare function startCameraSlide(session: CameraPanSession, applyPan: (dx: number, dy: number) => void, onFrame: () => void, slideOptions?: CameraSlideOptions): CameraSlideAnimation | null;
|
|
241
277
|
|
|
242
278
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
243
279
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -286,6 +322,7 @@ interface EditorOptions {
|
|
|
286
322
|
dragDistanceSquared?: number;
|
|
287
323
|
toolDefinitions?: ToolDefinition[];
|
|
288
324
|
initialToolId?: ToolId;
|
|
325
|
+
zoomRange?: ZoomRange;
|
|
289
326
|
}
|
|
290
327
|
type EditorListener = () => void;
|
|
291
328
|
declare class Editor {
|
|
@@ -296,6 +333,7 @@ declare class Editor {
|
|
|
296
333
|
viewport: Viewport;
|
|
297
334
|
readonly options: {
|
|
298
335
|
dragDistanceSquared: number;
|
|
336
|
+
zoomRange?: ZoomRange;
|
|
299
337
|
};
|
|
300
338
|
private drawStyle;
|
|
301
339
|
private readonly toolStateContext;
|
|
@@ -608,8 +646,12 @@ declare class HandIdleState extends StateNode {
|
|
|
608
646
|
|
|
609
647
|
declare class HandDraggingState extends StateNode {
|
|
610
648
|
static id: string;
|
|
649
|
+
private panSession;
|
|
650
|
+
onEnter(info?: ToolStateTransitionInfo): void;
|
|
611
651
|
onPointerMove(info?: ToolPointerMoveInfo): void;
|
|
652
|
+
getPanSession(): CameraPanSession | null;
|
|
612
653
|
onPointerUp(): void;
|
|
654
|
+
onExit(): void;
|
|
613
655
|
onCancel(): void;
|
|
614
656
|
onInterrupt(): void;
|
|
615
657
|
}
|
|
@@ -625,4 +667,4 @@ declare function decodePathToPoints(segments: {
|
|
|
625
667
|
y: number;
|
|
626
668
|
}[];
|
|
627
669
|
|
|
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 };
|
|
670
|
+
export { type Bounds, type CameraPanSession, type CameraSlideAnimation, type CameraSlideOptions, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DEFAULT_ZOOM_RANGE, 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, type ZoomRange, applyMove, applyResize, applyRotation, beginCameraPan, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, clampZoom, 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,37 @@ 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
|
+
interface ZoomRange {
|
|
173
|
+
min: number;
|
|
174
|
+
max: number;
|
|
175
|
+
}
|
|
176
|
+
declare const DEFAULT_ZOOM_RANGE: ZoomRange;
|
|
177
|
+
declare function clampZoom(zoom: number, range?: ZoomRange): number;
|
|
178
|
+
declare function zoomViewport(viewport: Viewport, factor: number, centerX?: number, centerY?: number, zoomRange?: ZoomRange): Viewport;
|
|
179
|
+
|
|
152
180
|
interface IEditor {
|
|
153
181
|
getZoomLevel(): number;
|
|
182
|
+
readonly viewport: Viewport;
|
|
154
183
|
options: {
|
|
155
184
|
dragDistanceSquared: number;
|
|
156
185
|
};
|
|
@@ -180,15 +209,20 @@ interface IEditor {
|
|
|
180
209
|
fill: FillStyle;
|
|
181
210
|
size: SizeStyle;
|
|
182
211
|
}>): void;
|
|
212
|
+
setViewport(partial: Partial<Viewport>): void;
|
|
183
213
|
panBy(dx: number, dy: number): void;
|
|
184
214
|
}
|
|
185
215
|
|
|
186
216
|
interface ToolPointerDownInfo {
|
|
187
217
|
point: Vec3;
|
|
218
|
+
screenX?: number;
|
|
219
|
+
screenY?: number;
|
|
188
220
|
}
|
|
189
221
|
interface ToolPointerMoveInfo {
|
|
190
222
|
screenDeltaX?: number;
|
|
191
223
|
screenDeltaY?: number;
|
|
224
|
+
screenX?: number;
|
|
225
|
+
screenY?: number;
|
|
192
226
|
}
|
|
193
227
|
interface ToolKeyInfo {
|
|
194
228
|
key: string;
|
|
@@ -217,27 +251,29 @@ declare abstract class StateNode {
|
|
|
217
251
|
onInterrupt(): void;
|
|
218
252
|
}
|
|
219
253
|
|
|
220
|
-
interface
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
254
|
+
interface CameraPanSession {
|
|
255
|
+
initialViewportX: number;
|
|
256
|
+
initialViewportY: number;
|
|
257
|
+
originScreenX: number;
|
|
258
|
+
originScreenY: number;
|
|
259
|
+
velocityX: number;
|
|
260
|
+
velocityY: number;
|
|
261
|
+
previousScreenX: number;
|
|
262
|
+
previousScreenY: number;
|
|
263
|
+
lastMoveTime: number;
|
|
264
|
+
}
|
|
265
|
+
declare function beginCameraPan(viewport: Viewport, screenX: number, screenY: number): CameraPanSession;
|
|
266
|
+
declare function moveCameraPan(session: CameraPanSession, currentScreenX: number, currentScreenY: number): {
|
|
227
267
|
x: number;
|
|
228
268
|
y: number;
|
|
229
269
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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;
|
|
270
|
+
interface CameraSlideAnimation {
|
|
271
|
+
stop: () => void;
|
|
272
|
+
}
|
|
273
|
+
interface CameraSlideOptions {
|
|
274
|
+
friction?: number;
|
|
275
|
+
}
|
|
276
|
+
declare function startCameraSlide(session: CameraPanSession, applyPan: (dx: number, dy: number) => void, onFrame: () => void, slideOptions?: CameraSlideOptions): CameraSlideAnimation | null;
|
|
241
277
|
|
|
242
278
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
243
279
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -286,6 +322,7 @@ interface EditorOptions {
|
|
|
286
322
|
dragDistanceSquared?: number;
|
|
287
323
|
toolDefinitions?: ToolDefinition[];
|
|
288
324
|
initialToolId?: ToolId;
|
|
325
|
+
zoomRange?: ZoomRange;
|
|
289
326
|
}
|
|
290
327
|
type EditorListener = () => void;
|
|
291
328
|
declare class Editor {
|
|
@@ -296,6 +333,7 @@ declare class Editor {
|
|
|
296
333
|
viewport: Viewport;
|
|
297
334
|
readonly options: {
|
|
298
335
|
dragDistanceSquared: number;
|
|
336
|
+
zoomRange?: ZoomRange;
|
|
299
337
|
};
|
|
300
338
|
private drawStyle;
|
|
301
339
|
private readonly toolStateContext;
|
|
@@ -608,8 +646,12 @@ declare class HandIdleState extends StateNode {
|
|
|
608
646
|
|
|
609
647
|
declare class HandDraggingState extends StateNode {
|
|
610
648
|
static id: string;
|
|
649
|
+
private panSession;
|
|
650
|
+
onEnter(info?: ToolStateTransitionInfo): void;
|
|
611
651
|
onPointerMove(info?: ToolPointerMoveInfo): void;
|
|
652
|
+
getPanSession(): CameraPanSession | null;
|
|
612
653
|
onPointerUp(): void;
|
|
654
|
+
onExit(): void;
|
|
613
655
|
onCancel(): void;
|
|
614
656
|
onInterrupt(): void;
|
|
615
657
|
}
|
|
@@ -625,4 +667,4 @@ declare function decodePathToPoints(segments: {
|
|
|
625
667
|
y: number;
|
|
626
668
|
}[];
|
|
627
669
|
|
|
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 };
|
|
670
|
+
export { type Bounds, type CameraPanSession, type CameraSlideAnimation, type CameraSlideOptions, CanvasRenderer, CircleDrawingState, CircleIdleState, type ColorStyle, DEFAULT_COLORS, DEFAULT_ZOOM_RANGE, 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, type ZoomRange, applyMove, applyResize, applyRotation, beginCameraPan, boundsContainPoint, boundsIntersect, boundsOf, buildStartPositions, buildTransformSnapshots, clampZoom, 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
|
@@ -247,8 +247,13 @@ function setViewport(viewport, updater) {
|
|
|
247
247
|
function panViewport(viewport, dx, dy) {
|
|
248
248
|
return { ...viewport, x: viewport.x + dx, y: viewport.y + dy };
|
|
249
249
|
}
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
var DEFAULT_ZOOM_RANGE = { min: 0.1, max: 4 };
|
|
251
|
+
function clampZoom(zoom, range) {
|
|
252
|
+
const { min, max } = range ?? DEFAULT_ZOOM_RANGE;
|
|
253
|
+
return Math.max(min, Math.min(max, zoom));
|
|
254
|
+
}
|
|
255
|
+
function zoomViewport(viewport, factor, centerX, centerY, zoomRange) {
|
|
256
|
+
const zoom = clampZoom(viewport.zoom * factor, zoomRange);
|
|
252
257
|
if (centerX == null || centerY == null) {
|
|
253
258
|
return { ...viewport, zoom };
|
|
254
259
|
}
|
|
@@ -258,6 +263,90 @@ function zoomViewport(viewport, factor, centerX, centerY) {
|
|
|
258
263
|
return { x, y, zoom };
|
|
259
264
|
}
|
|
260
265
|
|
|
266
|
+
// src/canvas/cameraPan.ts
|
|
267
|
+
var VELOCITY_LERP_FACTOR = 0.5;
|
|
268
|
+
var VELOCITY_ZERO_THRESHOLD = 0.01;
|
|
269
|
+
function beginCameraPan(viewport, screenX, screenY) {
|
|
270
|
+
return {
|
|
271
|
+
initialViewportX: viewport.x,
|
|
272
|
+
initialViewportY: viewport.y,
|
|
273
|
+
originScreenX: screenX,
|
|
274
|
+
originScreenY: screenY,
|
|
275
|
+
velocityX: 0,
|
|
276
|
+
velocityY: 0,
|
|
277
|
+
previousScreenX: screenX,
|
|
278
|
+
previousScreenY: screenY,
|
|
279
|
+
lastMoveTime: performance.now()
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function moveCameraPan(session, currentScreenX, currentScreenY) {
|
|
283
|
+
const now = performance.now();
|
|
284
|
+
const elapsed = now - session.lastMoveTime;
|
|
285
|
+
if (elapsed > 0) {
|
|
286
|
+
const moveDx = currentScreenX - session.previousScreenX;
|
|
287
|
+
const moveDy = currentScreenY - session.previousScreenY;
|
|
288
|
+
const moveLen = Math.hypot(moveDx, moveDy);
|
|
289
|
+
if (moveLen > 0) {
|
|
290
|
+
const dirX = moveDx / moveLen;
|
|
291
|
+
const dirY = moveDy / moveLen;
|
|
292
|
+
const speed = moveLen / elapsed;
|
|
293
|
+
session.velocityX += (dirX * speed - session.velocityX) * VELOCITY_LERP_FACTOR;
|
|
294
|
+
session.velocityY += (dirY * speed - session.velocityY) * VELOCITY_LERP_FACTOR;
|
|
295
|
+
}
|
|
296
|
+
if (Math.abs(session.velocityX) < VELOCITY_ZERO_THRESHOLD) session.velocityX = 0;
|
|
297
|
+
if (Math.abs(session.velocityY) < VELOCITY_ZERO_THRESHOLD) session.velocityY = 0;
|
|
298
|
+
}
|
|
299
|
+
session.previousScreenX = currentScreenX;
|
|
300
|
+
session.previousScreenY = currentScreenY;
|
|
301
|
+
session.lastMoveTime = now;
|
|
302
|
+
return {
|
|
303
|
+
x: session.initialViewportX + (currentScreenX - session.originScreenX),
|
|
304
|
+
y: session.initialViewportY + (currentScreenY - session.originScreenY)
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
var SLIDE_FRICTION = 0.92;
|
|
308
|
+
var SLIDE_MIN_SPEED = 0.01;
|
|
309
|
+
var SLIDE_MAX_SPEED = 2;
|
|
310
|
+
var SLIDE_MIN_VELOCITY_TO_START = 0.1;
|
|
311
|
+
function startCameraSlide(session, applyPan, onFrame, slideOptions) {
|
|
312
|
+
const friction = slideOptions?.friction ?? SLIDE_FRICTION;
|
|
313
|
+
const timeSinceLastMove = performance.now() - session.lastMoveTime;
|
|
314
|
+
const FRAME_DURATION = 16;
|
|
315
|
+
const decayFactor = Math.pow(1 - VELOCITY_LERP_FACTOR, timeSinceLastMove / FRAME_DURATION);
|
|
316
|
+
const effectiveVx = session.velocityX * decayFactor;
|
|
317
|
+
const effectiveVy = session.velocityY * decayFactor;
|
|
318
|
+
const speed = Math.hypot(effectiveVx, effectiveVy);
|
|
319
|
+
const clampedSpeed = Math.min(speed, SLIDE_MAX_SPEED);
|
|
320
|
+
if (clampedSpeed < SLIDE_MIN_VELOCITY_TO_START) return null;
|
|
321
|
+
const dirX = effectiveVx / speed;
|
|
322
|
+
const dirY = effectiveVy / speed;
|
|
323
|
+
let currentSpeed = clampedSpeed;
|
|
324
|
+
let lastTime = performance.now();
|
|
325
|
+
let rafId = 0;
|
|
326
|
+
const tick = () => {
|
|
327
|
+
const now = performance.now();
|
|
328
|
+
const elapsed = now - lastTime;
|
|
329
|
+
lastTime = now;
|
|
330
|
+
applyPan(dirX * currentSpeed * elapsed, dirY * currentSpeed * elapsed);
|
|
331
|
+
onFrame();
|
|
332
|
+
currentSpeed *= friction;
|
|
333
|
+
if (currentSpeed < SLIDE_MIN_SPEED) {
|
|
334
|
+
rafId = 0;
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
rafId = requestAnimationFrame(tick);
|
|
338
|
+
};
|
|
339
|
+
rafId = requestAnimationFrame(tick);
|
|
340
|
+
return {
|
|
341
|
+
stop() {
|
|
342
|
+
if (rafId !== 0) {
|
|
343
|
+
cancelAnimationFrame(rafId);
|
|
344
|
+
rafId = 0;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
261
350
|
// src/utils/colors.ts
|
|
262
351
|
var DARK_COLORS = {
|
|
263
352
|
black: "#f0f0f0",
|
|
@@ -1490,16 +1579,29 @@ var HandIdleState = class extends StateNode {
|
|
|
1490
1579
|
// src/tools/hand/states/HandDraggingState.ts
|
|
1491
1580
|
var HandDraggingState = class extends StateNode {
|
|
1492
1581
|
static id = "hand_dragging";
|
|
1582
|
+
panSession = null;
|
|
1583
|
+
onEnter(info) {
|
|
1584
|
+
const downInfo = info;
|
|
1585
|
+
const screenX = downInfo?.screenX ?? 0;
|
|
1586
|
+
const screenY = downInfo?.screenY ?? 0;
|
|
1587
|
+
this.panSession = beginCameraPan(this.editor.viewport, screenX, screenY);
|
|
1588
|
+
}
|
|
1493
1589
|
onPointerMove(info) {
|
|
1494
|
-
|
|
1495
|
-
const
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
this.editor.
|
|
1590
|
+
if (!this.panSession) return;
|
|
1591
|
+
const screenX = info?.screenX ?? 0;
|
|
1592
|
+
const screenY = info?.screenY ?? 0;
|
|
1593
|
+
const target = moveCameraPan(this.panSession, screenX, screenY);
|
|
1594
|
+
this.editor.setViewport({ x: target.x, y: target.y });
|
|
1595
|
+
}
|
|
1596
|
+
getPanSession() {
|
|
1597
|
+
return this.panSession;
|
|
1499
1598
|
}
|
|
1500
1599
|
onPointerUp() {
|
|
1501
1600
|
this.ctx.transition("hand_idle");
|
|
1502
1601
|
}
|
|
1602
|
+
onExit() {
|
|
1603
|
+
this.panSession = null;
|
|
1604
|
+
}
|
|
1503
1605
|
onCancel() {
|
|
1504
1606
|
this.ctx.transition("hand_idle");
|
|
1505
1607
|
}
|
|
@@ -1613,7 +1715,7 @@ var Editor = class {
|
|
|
1613
1715
|
historyBatchChanged = false;
|
|
1614
1716
|
// Creates a new editor instance with the given options (with defaults if not provided)
|
|
1615
1717
|
constructor(opts = {}) {
|
|
1616
|
-
this.options = { dragDistanceSquared: opts.dragDistanceSquared ?? DRAG_DISTANCE_SQUARED };
|
|
1718
|
+
this.options = { dragDistanceSquared: opts.dragDistanceSquared ?? DRAG_DISTANCE_SQUARED, zoomRange: opts.zoomRange };
|
|
1617
1719
|
this.lastDocumentSnapshot = this.getDocumentSnapshot();
|
|
1618
1720
|
this.store.listen(() => {
|
|
1619
1721
|
this.captureDocumentHistory();
|
|
@@ -1727,7 +1829,7 @@ var Editor = class {
|
|
|
1727
1829
|
this.viewport = {
|
|
1728
1830
|
x: partial.x ?? this.viewport.x,
|
|
1729
1831
|
y: partial.y ?? this.viewport.y,
|
|
1730
|
-
zoom:
|
|
1832
|
+
zoom: clampZoom(rawZoom, this.options.zoomRange)
|
|
1731
1833
|
};
|
|
1732
1834
|
this.emitChange();
|
|
1733
1835
|
}
|
|
@@ -1738,7 +1840,7 @@ var Editor = class {
|
|
|
1738
1840
|
});
|
|
1739
1841
|
}
|
|
1740
1842
|
zoomAt(factor, screenX, screenY) {
|
|
1741
|
-
this.viewport = zoomViewport(this.viewport, factor, screenX, screenY);
|
|
1843
|
+
this.viewport = zoomViewport(this.viewport, factor, screenX, screenY, this.options.zoomRange);
|
|
1742
1844
|
this.emitChange();
|
|
1743
1845
|
}
|
|
1744
1846
|
deleteShapes(ids) {
|
|
@@ -2158,6 +2260,6 @@ function applyResize(editor, handle, startBounds, startShapes, pointer, lockAspe
|
|
|
2158
2260
|
}
|
|
2159
2261
|
}
|
|
2160
2262
|
|
|
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 };
|
|
2263
|
+
export { CanvasRenderer, CircleDrawingState, CircleIdleState, DEFAULT_COLORS, DEFAULT_ZOOM_RANGE, 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, clampZoom, 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
2264
|
//# sourceMappingURL=index.js.map
|
|
2163
2265
|
//# sourceMappingURL=index.js.map
|