@tsdraw/core 0.8.4 → 0.9.0
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 +119 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +117 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -169,7 +169,13 @@ declare function setViewport(viewport: Viewport, updater: {
|
|
|
169
169
|
zoom?: number;
|
|
170
170
|
}): Viewport;
|
|
171
171
|
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
172
|
-
|
|
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;
|
|
173
179
|
|
|
174
180
|
interface IEditor {
|
|
175
181
|
getZoomLevel(): number;
|
|
@@ -264,7 +270,10 @@ declare function moveCameraPan(session: CameraPanSession, currentScreenX: number
|
|
|
264
270
|
interface CameraSlideAnimation {
|
|
265
271
|
stop: () => void;
|
|
266
272
|
}
|
|
267
|
-
|
|
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;
|
|
268
277
|
|
|
269
278
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
270
279
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -273,7 +282,8 @@ interface ICanvasRenderer {
|
|
|
273
282
|
render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
|
|
274
283
|
}
|
|
275
284
|
declare class CanvasRenderer implements ICanvasRenderer {
|
|
276
|
-
private
|
|
285
|
+
private _theme;
|
|
286
|
+
get theme(): TsdrawRenderTheme;
|
|
277
287
|
setTheme(theme: TsdrawRenderTheme): void;
|
|
278
288
|
render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
|
|
279
289
|
private paintStroke;
|
|
@@ -281,6 +291,22 @@ declare class CanvasRenderer implements ICanvasRenderer {
|
|
|
281
291
|
private paintClosedShapeFill;
|
|
282
292
|
}
|
|
283
293
|
|
|
294
|
+
type TsdrawBackgroundType = 'blank' | 'lines' | 'grid' | 'dots';
|
|
295
|
+
interface TsdrawBackgroundPreset {
|
|
296
|
+
type: TsdrawBackgroundType;
|
|
297
|
+
color?: string;
|
|
298
|
+
colorDark?: string;
|
|
299
|
+
spacing?: number;
|
|
300
|
+
size?: number;
|
|
301
|
+
opacity?: number;
|
|
302
|
+
}
|
|
303
|
+
interface TsdrawBackgroundCustom {
|
|
304
|
+
type: 'custom';
|
|
305
|
+
render: (ctx: CanvasRenderingContext2D, viewport: Viewport, canvasWidth: number, canvasHeight: number) => void;
|
|
306
|
+
}
|
|
307
|
+
type TsdrawBackgroundOptions = TsdrawBackgroundPreset | TsdrawBackgroundCustom;
|
|
308
|
+
declare function renderCanvasBackground(ctx: CanvasRenderingContext2D, viewport: Viewport, canvasWidth: number, canvasHeight: number, options: TsdrawBackgroundOptions | undefined, theme: TsdrawRenderTheme): void;
|
|
309
|
+
|
|
284
310
|
type DefaultToolId = 'pen' | 'eraser' | 'select' | 'hand' | 'square' | 'circle';
|
|
285
311
|
type ToolId = DefaultToolId | (string & {});
|
|
286
312
|
interface ToolDefinition {
|
|
@@ -313,6 +339,7 @@ interface EditorOptions {
|
|
|
313
339
|
dragDistanceSquared?: number;
|
|
314
340
|
toolDefinitions?: ToolDefinition[];
|
|
315
341
|
initialToolId?: ToolId;
|
|
342
|
+
zoomRange?: ZoomRange;
|
|
316
343
|
}
|
|
317
344
|
type EditorListener = () => void;
|
|
318
345
|
declare class Editor {
|
|
@@ -323,6 +350,7 @@ declare class Editor {
|
|
|
323
350
|
viewport: Viewport;
|
|
324
351
|
readonly options: {
|
|
325
352
|
dragDistanceSquared: number;
|
|
353
|
+
zoomRange?: ZoomRange;
|
|
326
354
|
};
|
|
327
355
|
private drawStyle;
|
|
328
356
|
private readonly toolStateContext;
|
|
@@ -656,4 +684,4 @@ declare function decodePathToPoints(segments: {
|
|
|
656
684
|
y: number;
|
|
657
685
|
}[];
|
|
658
686
|
|
|
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 };
|
|
687
|
+
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 TsdrawBackgroundCustom, type TsdrawBackgroundOptions, type TsdrawBackgroundPreset, type TsdrawBackgroundType, 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, renderCanvasBackground, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, startCameraSlide, zoomViewport };
|
package/dist/index.d.ts
CHANGED
|
@@ -169,7 +169,13 @@ declare function setViewport(viewport: Viewport, updater: {
|
|
|
169
169
|
zoom?: number;
|
|
170
170
|
}): Viewport;
|
|
171
171
|
declare function panViewport(viewport: Viewport, dx: number, dy: number): Viewport;
|
|
172
|
-
|
|
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;
|
|
173
179
|
|
|
174
180
|
interface IEditor {
|
|
175
181
|
getZoomLevel(): number;
|
|
@@ -264,7 +270,10 @@ declare function moveCameraPan(session: CameraPanSession, currentScreenX: number
|
|
|
264
270
|
interface CameraSlideAnimation {
|
|
265
271
|
stop: () => void;
|
|
266
272
|
}
|
|
267
|
-
|
|
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;
|
|
268
277
|
|
|
269
278
|
type TsdrawRenderTheme = 'light' | 'dark';
|
|
270
279
|
declare function resolveThemeColor(colorStyle: string, theme: TsdrawRenderTheme): string;
|
|
@@ -273,7 +282,8 @@ interface ICanvasRenderer {
|
|
|
273
282
|
render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
|
|
274
283
|
}
|
|
275
284
|
declare class CanvasRenderer implements ICanvasRenderer {
|
|
276
|
-
private
|
|
285
|
+
private _theme;
|
|
286
|
+
get theme(): TsdrawRenderTheme;
|
|
277
287
|
setTheme(theme: TsdrawRenderTheme): void;
|
|
278
288
|
render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
|
|
279
289
|
private paintStroke;
|
|
@@ -281,6 +291,22 @@ declare class CanvasRenderer implements ICanvasRenderer {
|
|
|
281
291
|
private paintClosedShapeFill;
|
|
282
292
|
}
|
|
283
293
|
|
|
294
|
+
type TsdrawBackgroundType = 'blank' | 'lines' | 'grid' | 'dots';
|
|
295
|
+
interface TsdrawBackgroundPreset {
|
|
296
|
+
type: TsdrawBackgroundType;
|
|
297
|
+
color?: string;
|
|
298
|
+
colorDark?: string;
|
|
299
|
+
spacing?: number;
|
|
300
|
+
size?: number;
|
|
301
|
+
opacity?: number;
|
|
302
|
+
}
|
|
303
|
+
interface TsdrawBackgroundCustom {
|
|
304
|
+
type: 'custom';
|
|
305
|
+
render: (ctx: CanvasRenderingContext2D, viewport: Viewport, canvasWidth: number, canvasHeight: number) => void;
|
|
306
|
+
}
|
|
307
|
+
type TsdrawBackgroundOptions = TsdrawBackgroundPreset | TsdrawBackgroundCustom;
|
|
308
|
+
declare function renderCanvasBackground(ctx: CanvasRenderingContext2D, viewport: Viewport, canvasWidth: number, canvasHeight: number, options: TsdrawBackgroundOptions | undefined, theme: TsdrawRenderTheme): void;
|
|
309
|
+
|
|
284
310
|
type DefaultToolId = 'pen' | 'eraser' | 'select' | 'hand' | 'square' | 'circle';
|
|
285
311
|
type ToolId = DefaultToolId | (string & {});
|
|
286
312
|
interface ToolDefinition {
|
|
@@ -313,6 +339,7 @@ interface EditorOptions {
|
|
|
313
339
|
dragDistanceSquared?: number;
|
|
314
340
|
toolDefinitions?: ToolDefinition[];
|
|
315
341
|
initialToolId?: ToolId;
|
|
342
|
+
zoomRange?: ZoomRange;
|
|
316
343
|
}
|
|
317
344
|
type EditorListener = () => void;
|
|
318
345
|
declare class Editor {
|
|
@@ -323,6 +350,7 @@ declare class Editor {
|
|
|
323
350
|
viewport: Viewport;
|
|
324
351
|
readonly options: {
|
|
325
352
|
dragDistanceSquared: number;
|
|
353
|
+
zoomRange?: ZoomRange;
|
|
326
354
|
};
|
|
327
355
|
private drawStyle;
|
|
328
356
|
private readonly toolStateContext;
|
|
@@ -656,4 +684,4 @@ declare function decodePathToPoints(segments: {
|
|
|
656
684
|
y: number;
|
|
657
685
|
}[];
|
|
658
686
|
|
|
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 };
|
|
687
|
+
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 TsdrawBackgroundCustom, type TsdrawBackgroundOptions, type TsdrawBackgroundPreset, type TsdrawBackgroundType, 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, renderCanvasBackground, 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
|
}
|
|
@@ -303,7 +308,8 @@ var SLIDE_FRICTION = 0.92;
|
|
|
303
308
|
var SLIDE_MIN_SPEED = 0.01;
|
|
304
309
|
var SLIDE_MAX_SPEED = 2;
|
|
305
310
|
var SLIDE_MIN_VELOCITY_TO_START = 0.1;
|
|
306
|
-
function startCameraSlide(session, applyPan, onFrame) {
|
|
311
|
+
function startCameraSlide(session, applyPan, onFrame, slideOptions) {
|
|
312
|
+
const friction = slideOptions?.friction ?? SLIDE_FRICTION;
|
|
307
313
|
const timeSinceLastMove = performance.now() - session.lastMoveTime;
|
|
308
314
|
const FRAME_DURATION = 16;
|
|
309
315
|
const decayFactor = Math.pow(1 - VELOCITY_LERP_FACTOR, timeSinceLastMove / FRAME_DURATION);
|
|
@@ -323,7 +329,7 @@ function startCameraSlide(session, applyPan, onFrame) {
|
|
|
323
329
|
lastTime = now;
|
|
324
330
|
applyPan(dirX * currentSpeed * elapsed, dirY * currentSpeed * elapsed);
|
|
325
331
|
onFrame();
|
|
326
|
-
currentSpeed *=
|
|
332
|
+
currentSpeed *= friction;
|
|
327
333
|
if (currentSpeed < SLIDE_MIN_SPEED) {
|
|
328
334
|
rafId = 0;
|
|
329
335
|
return;
|
|
@@ -364,9 +370,12 @@ function resolveThemeColor(colorStyle, theme) {
|
|
|
364
370
|
return DARK_COLORS[colorStyle] ?? lightThemeColor;
|
|
365
371
|
}
|
|
366
372
|
var CanvasRenderer = class {
|
|
367
|
-
|
|
373
|
+
_theme = "light";
|
|
374
|
+
get theme() {
|
|
375
|
+
return this._theme;
|
|
376
|
+
}
|
|
368
377
|
setTheme(theme) {
|
|
369
|
-
this.
|
|
378
|
+
this._theme = theme;
|
|
370
379
|
}
|
|
371
380
|
render(ctx, viewport, shapes) {
|
|
372
381
|
ctx.save();
|
|
@@ -384,7 +393,7 @@ var CanvasRenderer = class {
|
|
|
384
393
|
const width = (STROKE_WIDTHS[shape.props.size] ?? 3.5) * shape.props.scale;
|
|
385
394
|
const samples = flattenSegments(shape);
|
|
386
395
|
if (samples.length === 0) return;
|
|
387
|
-
const color = resolveThemeColor(shape.props.color, this.
|
|
396
|
+
const color = resolveThemeColor(shape.props.color, this._theme);
|
|
388
397
|
const fillStyle = shape.props.fill ?? "none";
|
|
389
398
|
if (shape.props.isClosed && fillStyle !== "none") {
|
|
390
399
|
this.paintClosedShapeFill(ctx, samples, color, fillStyle);
|
|
@@ -450,7 +459,7 @@ var CanvasRenderer = class {
|
|
|
450
459
|
ctx.fillStyle = color;
|
|
451
460
|
ctx.globalAlpha = 0.55;
|
|
452
461
|
} else if (fillStyle === "none") {
|
|
453
|
-
ctx.fillStyle = this.
|
|
462
|
+
ctx.fillStyle = this._theme === "dark" ? "#0f0f0f" : "#fafafa";
|
|
454
463
|
ctx.globalAlpha = 1;
|
|
455
464
|
} else {
|
|
456
465
|
ctx.fillStyle = color;
|
|
@@ -546,6 +555,102 @@ function getLineDash(dash, width) {
|
|
|
546
555
|
}
|
|
547
556
|
}
|
|
548
557
|
|
|
558
|
+
// src/canvas/backgroundRenderer.ts
|
|
559
|
+
var DEFAULT_SPACING = 20;
|
|
560
|
+
var DEFAULT_LINE_WIDTH = 0.5;
|
|
561
|
+
var DEFAULT_DOT_RADIUS = 1;
|
|
562
|
+
var DEFAULT_OPACITY = 0.25;
|
|
563
|
+
function resolvePresetPatternColor(colorLight, colorDark, theme) {
|
|
564
|
+
if (theme === "dark") return colorDark ?? colorLight ?? "#888888";
|
|
565
|
+
return colorLight ?? "#c0c0c0";
|
|
566
|
+
}
|
|
567
|
+
function visiblePageRect(viewport, canvasWidth, canvasHeight) {
|
|
568
|
+
return {
|
|
569
|
+
minX: (0 - viewport.x) / viewport.zoom,
|
|
570
|
+
minY: (0 - viewport.y) / viewport.zoom,
|
|
571
|
+
maxX: (canvasWidth - viewport.x) / viewport.zoom,
|
|
572
|
+
maxY: (canvasHeight - viewport.y) / viewport.zoom
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function drawHorizontalLines(ctx, visible, spacing, lineWidth, color, opacity) {
|
|
576
|
+
const startY = Math.floor(visible.minY / spacing) * spacing;
|
|
577
|
+
ctx.save();
|
|
578
|
+
ctx.strokeStyle = color;
|
|
579
|
+
ctx.lineWidth = lineWidth / ctx.getTransform().a;
|
|
580
|
+
ctx.globalAlpha = opacity;
|
|
581
|
+
ctx.beginPath();
|
|
582
|
+
for (let y = startY; y <= visible.maxY; y += spacing) {
|
|
583
|
+
ctx.moveTo(visible.minX, y);
|
|
584
|
+
ctx.lineTo(visible.maxX, y);
|
|
585
|
+
}
|
|
586
|
+
ctx.stroke();
|
|
587
|
+
ctx.restore();
|
|
588
|
+
}
|
|
589
|
+
function drawGridLines(ctx, visible, spacing, lineWidth, color, opacity) {
|
|
590
|
+
const startX = Math.floor(visible.minX / spacing) * spacing;
|
|
591
|
+
const startY = Math.floor(visible.minY / spacing) * spacing;
|
|
592
|
+
const compensatedWidth = lineWidth / ctx.getTransform().a;
|
|
593
|
+
ctx.save();
|
|
594
|
+
ctx.strokeStyle = color;
|
|
595
|
+
ctx.lineWidth = compensatedWidth;
|
|
596
|
+
ctx.globalAlpha = opacity;
|
|
597
|
+
ctx.beginPath();
|
|
598
|
+
for (let x = startX; x <= visible.maxX; x += spacing) {
|
|
599
|
+
ctx.moveTo(x, visible.minY);
|
|
600
|
+
ctx.lineTo(x, visible.maxY);
|
|
601
|
+
}
|
|
602
|
+
for (let y = startY; y <= visible.maxY; y += spacing) {
|
|
603
|
+
ctx.moveTo(visible.minX, y);
|
|
604
|
+
ctx.lineTo(visible.maxX, y);
|
|
605
|
+
}
|
|
606
|
+
ctx.stroke();
|
|
607
|
+
ctx.restore();
|
|
608
|
+
}
|
|
609
|
+
function drawDotPattern(ctx, visible, spacing, dotRadius, color, opacity) {
|
|
610
|
+
const startX = Math.floor(visible.minX / spacing) * spacing;
|
|
611
|
+
const startY = Math.floor(visible.minY / spacing) * spacing;
|
|
612
|
+
const compensatedRadius = dotRadius / ctx.getTransform().a;
|
|
613
|
+
ctx.save();
|
|
614
|
+
ctx.fillStyle = color;
|
|
615
|
+
ctx.globalAlpha = opacity;
|
|
616
|
+
ctx.beginPath();
|
|
617
|
+
for (let x = startX; x <= visible.maxX; x += spacing) {
|
|
618
|
+
for (let y = startY; y <= visible.maxY; y += spacing) {
|
|
619
|
+
ctx.moveTo(x + compensatedRadius, y);
|
|
620
|
+
ctx.arc(x, y, compensatedRadius, 0, Math.PI * 2);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
ctx.fill();
|
|
624
|
+
ctx.restore();
|
|
625
|
+
}
|
|
626
|
+
function renderCanvasBackground(ctx, viewport, canvasWidth, canvasHeight, options, theme) {
|
|
627
|
+
if (!options || options.type === "blank") return;
|
|
628
|
+
if (options.type === "custom") {
|
|
629
|
+
options.render(ctx, viewport, canvasWidth, canvasHeight);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
const spacing = options.spacing ?? DEFAULT_SPACING;
|
|
633
|
+
if (spacing <= 0) return;
|
|
634
|
+
const color = resolvePresetPatternColor(options.color, options.colorDark, theme);
|
|
635
|
+
const opacity = options.opacity ?? DEFAULT_OPACITY;
|
|
636
|
+
const visible = visiblePageRect(viewport, canvasWidth, canvasHeight);
|
|
637
|
+
ctx.save();
|
|
638
|
+
ctx.translate(viewport.x, viewport.y);
|
|
639
|
+
ctx.scale(viewport.zoom, viewport.zoom);
|
|
640
|
+
switch (options.type) {
|
|
641
|
+
case "lines":
|
|
642
|
+
drawHorizontalLines(ctx, visible, spacing, options.size ?? DEFAULT_LINE_WIDTH, color, opacity);
|
|
643
|
+
break;
|
|
644
|
+
case "grid":
|
|
645
|
+
drawGridLines(ctx, visible, spacing, options.size ?? DEFAULT_LINE_WIDTH, color, opacity);
|
|
646
|
+
break;
|
|
647
|
+
case "dots":
|
|
648
|
+
drawDotPattern(ctx, visible, spacing, options.size ?? DEFAULT_DOT_RADIUS, color, opacity);
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
ctx.restore();
|
|
652
|
+
}
|
|
653
|
+
|
|
549
654
|
// src/input/inputManager.ts
|
|
550
655
|
var InputManager = class {
|
|
551
656
|
_current = { x: 0, y: 0 };
|
|
@@ -1709,7 +1814,7 @@ var Editor = class {
|
|
|
1709
1814
|
historyBatchChanged = false;
|
|
1710
1815
|
// Creates a new editor instance with the given options (with defaults if not provided)
|
|
1711
1816
|
constructor(opts = {}) {
|
|
1712
|
-
this.options = { dragDistanceSquared: opts.dragDistanceSquared ?? DRAG_DISTANCE_SQUARED };
|
|
1817
|
+
this.options = { dragDistanceSquared: opts.dragDistanceSquared ?? DRAG_DISTANCE_SQUARED, zoomRange: opts.zoomRange };
|
|
1713
1818
|
this.lastDocumentSnapshot = this.getDocumentSnapshot();
|
|
1714
1819
|
this.store.listen(() => {
|
|
1715
1820
|
this.captureDocumentHistory();
|
|
@@ -1823,7 +1928,7 @@ var Editor = class {
|
|
|
1823
1928
|
this.viewport = {
|
|
1824
1929
|
x: partial.x ?? this.viewport.x,
|
|
1825
1930
|
y: partial.y ?? this.viewport.y,
|
|
1826
|
-
zoom:
|
|
1931
|
+
zoom: clampZoom(rawZoom, this.options.zoomRange)
|
|
1827
1932
|
};
|
|
1828
1933
|
this.emitChange();
|
|
1829
1934
|
}
|
|
@@ -1834,7 +1939,7 @@ var Editor = class {
|
|
|
1834
1939
|
});
|
|
1835
1940
|
}
|
|
1836
1941
|
zoomAt(factor, screenX, screenY) {
|
|
1837
|
-
this.viewport = zoomViewport(this.viewport, factor, screenX, screenY);
|
|
1942
|
+
this.viewport = zoomViewport(this.viewport, factor, screenX, screenY, this.options.zoomRange);
|
|
1838
1943
|
this.emitChange();
|
|
1839
1944
|
}
|
|
1840
1945
|
deleteShapes(ids) {
|
|
@@ -2254,6 +2359,6 @@ function applyResize(editor, handle, startBounds, startShapes, pointer, lockAspe
|
|
|
2254
2359
|
}
|
|
2255
2360
|
}
|
|
2256
2361
|
|
|
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 };
|
|
2362
|
+
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, renderCanvasBackground, resolveThemeColor, rotatePoint, screenToPage, segmentHitsShape, segmentTouchesPolyline, setViewport, shapePagePoints, sqDistance, startCameraSlide, zoomViewport };
|
|
2258
2363
|
//# sourceMappingURL=index.js.map
|
|
2259
2364
|
//# sourceMappingURL=index.js.map
|