@tsdraw/core 0.8.5 → 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.d.cts CHANGED
@@ -282,7 +282,8 @@ interface ICanvasRenderer {
282
282
  render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
283
283
  }
284
284
  declare class CanvasRenderer implements ICanvasRenderer {
285
- private theme;
285
+ private _theme;
286
+ get theme(): TsdrawRenderTheme;
286
287
  setTheme(theme: TsdrawRenderTheme): void;
287
288
  render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
288
289
  private paintStroke;
@@ -290,6 +291,22 @@ declare class CanvasRenderer implements ICanvasRenderer {
290
291
  private paintClosedShapeFill;
291
292
  }
292
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
+
293
310
  type DefaultToolId = 'pen' | 'eraser' | 'select' | 'hand' | 'square' | 'circle';
294
311
  type ToolId = DefaultToolId | (string & {});
295
312
  interface ToolDefinition {
@@ -667,4 +684,4 @@ declare function decodePathToPoints(segments: {
667
684
  y: number;
668
685
  }[];
669
686
 
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 };
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
@@ -282,7 +282,8 @@ interface ICanvasRenderer {
282
282
  render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
283
283
  }
284
284
  declare class CanvasRenderer implements ICanvasRenderer {
285
- private theme;
285
+ private _theme;
286
+ get theme(): TsdrawRenderTheme;
286
287
  setTheme(theme: TsdrawRenderTheme): void;
287
288
  render(ctx: CanvasRenderingContext2D, viewport: Viewport, shapes: Shape[]): void;
288
289
  private paintStroke;
@@ -290,6 +291,22 @@ declare class CanvasRenderer implements ICanvasRenderer {
290
291
  private paintClosedShapeFill;
291
292
  }
292
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
+
293
310
  type DefaultToolId = 'pen' | 'eraser' | 'select' | 'hand' | 'square' | 'circle';
294
311
  type ToolId = DefaultToolId | (string & {});
295
312
  interface ToolDefinition {
@@ -667,4 +684,4 @@ declare function decodePathToPoints(segments: {
667
684
  y: number;
668
685
  }[];
669
686
 
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 };
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
@@ -370,9 +370,12 @@ function resolveThemeColor(colorStyle, theme) {
370
370
  return DARK_COLORS[colorStyle] ?? lightThemeColor;
371
371
  }
372
372
  var CanvasRenderer = class {
373
- theme = "light";
373
+ _theme = "light";
374
+ get theme() {
375
+ return this._theme;
376
+ }
374
377
  setTheme(theme) {
375
- this.theme = theme;
378
+ this._theme = theme;
376
379
  }
377
380
  render(ctx, viewport, shapes) {
378
381
  ctx.save();
@@ -390,7 +393,7 @@ var CanvasRenderer = class {
390
393
  const width = (STROKE_WIDTHS[shape.props.size] ?? 3.5) * shape.props.scale;
391
394
  const samples = flattenSegments(shape);
392
395
  if (samples.length === 0) return;
393
- const color = resolveThemeColor(shape.props.color, this.theme);
396
+ const color = resolveThemeColor(shape.props.color, this._theme);
394
397
  const fillStyle = shape.props.fill ?? "none";
395
398
  if (shape.props.isClosed && fillStyle !== "none") {
396
399
  this.paintClosedShapeFill(ctx, samples, color, fillStyle);
@@ -456,7 +459,7 @@ var CanvasRenderer = class {
456
459
  ctx.fillStyle = color;
457
460
  ctx.globalAlpha = 0.55;
458
461
  } else if (fillStyle === "none") {
459
- ctx.fillStyle = this.theme === "dark" ? "#0f0f0f" : "#fafafa";
462
+ ctx.fillStyle = this._theme === "dark" ? "#0f0f0f" : "#fafafa";
460
463
  ctx.globalAlpha = 1;
461
464
  } else {
462
465
  ctx.fillStyle = color;
@@ -552,6 +555,102 @@ function getLineDash(dash, width) {
552
555
  }
553
556
  }
554
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
+
555
654
  // src/input/inputManager.ts
556
655
  var InputManager = class {
557
656
  _current = { x: 0, y: 0 };
@@ -2260,6 +2359,6 @@ function applyResize(editor, handle, startBounds, startShapes, pointer, lockAspe
2260
2359
  }
2261
2360
  }
2262
2361
 
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 };
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 };
2264
2363
  //# sourceMappingURL=index.js.map
2265
2364
  //# sourceMappingURL=index.js.map