@nightshadeui/canvas 2.11.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.
@@ -0,0 +1,25 @@
1
+ import { Box } from '@nightshadeui/util';
2
+ export declare class CanvasBoxSelect {
3
+ private config;
4
+ private inputState;
5
+ private objectRegistry;
6
+ private selection;
7
+ private space;
8
+ private selectionOriginPos;
9
+ private initialSelectionIds;
10
+ private objectBoxes;
11
+ isSelecting(): boolean;
12
+ onUiDragStart(ev: MouseEvent): void;
13
+ onUiDragMove(ev: MouseEvent): void;
14
+ onUiDragEnd(ev: MouseEvent): void;
15
+ getSelectionBox(): Box | null;
16
+ getSelectionStyle(): {
17
+ left: string;
18
+ top: string;
19
+ width: string;
20
+ height: string;
21
+ } | null;
22
+ private stopSelecting;
23
+ private captureObjectBoxes;
24
+ private updateSelection;
25
+ }
@@ -0,0 +1,9 @@
1
+ export interface CanvasConfigSpec {
2
+ autoCenter?: boolean;
3
+ allowMultiSelect?: boolean;
4
+ }
5
+ export declare class CanvasConfig {
6
+ autoCenter: boolean;
7
+ allowMultiSelect: boolean;
8
+ set(config: Partial<CanvasConfigSpec>): void;
9
+ }
@@ -0,0 +1,29 @@
1
+ import { Mesh } from 'mesh-ioc';
2
+ import { CanvasBoxSelect } from './CanvasBoxSelect.js';
3
+ import { CanvasConfig, CanvasConfigSpec } from './CanvasConfig.js';
4
+ import { CanvasEvents } from './CanvasEvents.js';
5
+ import { CanvasInputState } from './CanvasInputState.js';
6
+ import { CanvasObjectRegistry } from './CanvasObjectRegistry.js';
7
+ import { CanvasPan } from './CanvasPan.js';
8
+ import { CanvasSelection } from './CanvasSelection.js';
9
+ import { CanvasSpace } from './CanvasSpace.js';
10
+ import { CanvasUiEvents } from './CanvasUiEvents.js';
11
+ import { CanvasViewport } from './CanvasViewport.js';
12
+ import { CanvasZoom } from './CanvasZoom.js';
13
+ export declare class CanvasController {
14
+ mesh: Mesh;
15
+ boxSelect: CanvasBoxSelect;
16
+ config: CanvasConfig;
17
+ space: CanvasSpace;
18
+ viewport: CanvasViewport;
19
+ pan: CanvasPan;
20
+ events: CanvasEvents;
21
+ inputState: CanvasInputState;
22
+ objectRegistry: CanvasObjectRegistry;
23
+ selection: CanvasSelection;
24
+ uiEvents: CanvasUiEvents;
25
+ zoom: CanvasZoom;
26
+ constructor(config?: CanvasConfigSpec);
27
+ mount(viewportEl: HTMLElement): void;
28
+ unmount(): void;
29
+ }
@@ -0,0 +1,13 @@
1
+ import { Event } from 'nanoevent';
2
+ import { CanvasObjectPos } from './CanvasObjectController.js';
3
+ export declare class CanvasEvents {
4
+ mounted: Event<void>;
5
+ unmounted: Event<void>;
6
+ selectionChanged: Event<string[]>;
7
+ dragMove: Event<MouseEvent>;
8
+ dragEnd: Event<MouseEvent>;
9
+ objectPosUpdated: Event<{
10
+ objectId: string;
11
+ pos: CanvasObjectPos;
12
+ }>;
13
+ }
@@ -0,0 +1,23 @@
1
+ export declare class CanvasInputState {
2
+ lastMousePos: {
3
+ x: number;
4
+ y: number;
5
+ };
6
+ lmbPressed: boolean;
7
+ mmbPressed: boolean;
8
+ rmbPressed: boolean;
9
+ altKey: boolean;
10
+ ctrlKey: boolean;
11
+ metaKey: boolean;
12
+ shiftKey: boolean;
13
+ private events;
14
+ private windowEvents;
15
+ init(): void;
16
+ get ctrlOrMetaKey(): boolean;
17
+ private onMouseDown;
18
+ private onMouseMove;
19
+ private onMouseUp;
20
+ private onKeyDown;
21
+ private onKeyUp;
22
+ private updateModifiers;
23
+ }
@@ -0,0 +1,13 @@
1
+ export declare class CanvasMove {
2
+ private events;
3
+ private selection;
4
+ private objectRegistry;
5
+ private space;
6
+ private movingIds;
7
+ private moveOriginPos;
8
+ init(): void;
9
+ isMoving(objectId: string): boolean;
10
+ startMovingSelection(ev: MouseEvent): void;
11
+ private onDragMove;
12
+ stopMovingSelection(): void;
13
+ }
@@ -0,0 +1,98 @@
1
+ import { Box, Point } from '@nightshadeui/util';
2
+ import { CanvasResizeDirection, CanvasResizeMode } from './types.js';
3
+ export interface CanvasObjectPos {
4
+ x: number;
5
+ y: number;
6
+ w?: number;
7
+ h?: number;
8
+ }
9
+ export declare class CanvasObjectController {
10
+ private config;
11
+ private events;
12
+ private selection;
13
+ private move;
14
+ private space;
15
+ objectId: string;
16
+ element: HTMLElement | null;
17
+ private selectable;
18
+ private movable;
19
+ private snapToGrid;
20
+ private resizable;
21
+ private bounds;
22
+ private pos;
23
+ private localPos;
24
+ private prevLocalPos;
25
+ private resizingDirection;
26
+ private resizingBounds;
27
+ constructor(objectId: string);
28
+ setElement(element: HTMLElement | null): void;
29
+ getPos(): CanvasObjectPos;
30
+ setPos(pos: CanvasObjectPos): void;
31
+ getBounds(): Box;
32
+ setBounds(bounds: Box): void;
33
+ isSelectable(): boolean;
34
+ setSelectable(selectable: boolean): void;
35
+ isSelected(): boolean;
36
+ setSelected(isSelected: boolean): void;
37
+ isMovable(): boolean;
38
+ setMovable(movable: boolean): void;
39
+ isSnapToGrid(): boolean;
40
+ setSnapToGrid(snapToGrid: boolean): void;
41
+ isResizable(): CanvasResizeMode;
42
+ setResizable(resizable: CanvasResizeMode): void;
43
+ getCanvasCoords(): CanvasObjectPos;
44
+ getStyle(): {
45
+ position: string;
46
+ left: string;
47
+ top: string;
48
+ width: string | undefined;
49
+ height: string | undefined;
50
+ };
51
+ isMoving(): boolean;
52
+ isResizing(): boolean;
53
+ commitNewPos(newPos: CanvasObjectPos): void;
54
+ /**
55
+ * Click handles selection
56
+ * Shift/Ctrl/Meta key allows multi-select, if allowed by canvas config
57
+ */
58
+ onUiClick(ev: MouseEvent): void;
59
+ /**
60
+ * Dragging starts moving selected objects, if allowed.
61
+ * If not selected, single selection is performed first, then dragging starts.
62
+ */
63
+ onUiDragStart(ev: MouseEvent): void;
64
+ /**
65
+ * Drag move is re-emitted to global canvas events, so that each selected object moves.
66
+ * CanvasMove will call onMoveOffset on objects that are currently moving.
67
+ */
68
+ onUiDragMove(ev: MouseEvent): void;
69
+ /**
70
+ * Drag end is re-emitted to global canvas events, so that each selected object stops moving.
71
+ * CanvasMove will call onMoveEnd on objects that are currently moving.
72
+ */
73
+ onUiDragEnd(ev: MouseEvent): void;
74
+ /**
75
+ * Move start is called by CanvasMove when selected objects starts moving.
76
+ * It saves the previous local position, so that the offset can be calculated.
77
+ */
78
+ onMoveStart(): void;
79
+ /**
80
+ * Move offset is called by CanvasMove when selected objects moves.
81
+ * It calculates the new local position based on the previous local position and the offset.
82
+ */
83
+ onMoveOffset(offset: Point): void;
84
+ /**
85
+ * Move end is called by CanvasMove when selected objects stops moving.
86
+ * It commits the new local position to the object.
87
+ */
88
+ onMoveEnd(): void;
89
+ startResizing(direction: CanvasResizeDirection): void;
90
+ onResizeMove(ev: MouseEvent): void;
91
+ onResizeEnd(): void;
92
+ getResizeDirections(): CanvasResizeDirection[];
93
+ private getObjectBounds;
94
+ private canResizeInDirection;
95
+ private recalcLocalPos;
96
+ private maybeRound;
97
+ private getResizingUpdates;
98
+ }
@@ -0,0 +1,8 @@
1
+ import { CanvasObjectController } from './CanvasObjectController.js';
2
+ export declare class CanvasObjectRegistry {
3
+ private objects;
4
+ register(controller: CanvasObjectController): void;
5
+ unregister(objectId: string): void;
6
+ get(objectId: string): CanvasObjectController | null;
7
+ getAll(): CanvasObjectController[];
8
+ }
@@ -0,0 +1,11 @@
1
+ export declare class CanvasPan {
2
+ private viewport;
3
+ private events;
4
+ private windowEvents;
5
+ private isPanning;
6
+ init(): void;
7
+ onMouseDown(ev: MouseEvent): void;
8
+ stopPanning(): void;
9
+ private onMouseMove;
10
+ private onMouseUp;
11
+ }
@@ -0,0 +1,17 @@
1
+ export declare class CanvasSelection {
2
+ selectedIds: Set<string>;
3
+ private events;
4
+ get size(): number;
5
+ getSelectedIds(): string[];
6
+ getFirst(): string;
7
+ isSelected(id: string): boolean;
8
+ isSingleSelected(id: string): boolean;
9
+ setSelectedIds(ids: Iterable<string>): void;
10
+ selectSingle(id: string): void;
11
+ addToSelection(...ids: string[]): void;
12
+ removeFromSelection(...ids: string[]): void;
13
+ toggleSelection(id: string): void;
14
+ deselectAll(): void;
15
+ private notifySelectionChanged;
16
+ setSelected(id: string, isSelected: boolean): void;
17
+ }
@@ -0,0 +1,19 @@
1
+ import { Box, Point } from '@nightshadeui/util';
2
+ export declare class CanvasSpace {
3
+ zoom: number;
4
+ cellSize: number;
5
+ scrollPos: Point;
6
+ viewportBox: Box;
7
+ canvasOrigin: Point;
8
+ canvasSize: Point;
9
+ localToCanvas(pos: Point): Point;
10
+ canvasToLocal(pos: Point): Point;
11
+ viewportToCanvas(pos: Point): Point;
12
+ canvasToViewport(pos: Point): Point;
13
+ viewportToLocal(pos: Point): Point;
14
+ localToViewport(pos: Point): Point;
15
+ pageToViewport(pos: Point): Point;
16
+ pageToCanvas(pos: Point): Point;
17
+ pageToLocal(pos: Point): Point;
18
+ getViewportCenterInLocal(): Point;
19
+ }
@@ -0,0 +1,18 @@
1
+ export declare class CanvasUiEvents {
2
+ private events;
3
+ private inputState;
4
+ private windowEvents;
5
+ private lastMouseDownPos;
6
+ private lastMouseDownTarget;
7
+ private dragTarget;
8
+ private inClickVicinity;
9
+ private dragDistance;
10
+ init(): void;
11
+ private onMouseDown;
12
+ private onMouseMove;
13
+ private onMouseUp;
14
+ private onKeyDown;
15
+ private dispatchActivate;
16
+ private isDragAllowed;
17
+ private cloneMouseEvent;
18
+ }
@@ -0,0 +1,39 @@
1
+ import { Point } from '@nightshadeui/util';
2
+ /**
3
+ * Coordinate systems:
4
+ * - page: MouseEvent pageX/pageY.
5
+ * - viewport: (0, 0) at viewport element top-left, unscaled.
6
+ * - canvas: (0, 0) at canvas content top-left, scaled by zoom.
7
+ * - local: (0, 0) at canvas origin, measured in cell units.
8
+ */
9
+ export declare class CanvasViewport {
10
+ viewportEl: HTMLElement | null;
11
+ private windowEvents;
12
+ private config;
13
+ private space;
14
+ mount(viewportEl: HTMLElement): void;
15
+ destroy(): void;
16
+ getCanvasStyle(): {
17
+ background: string;
18
+ width: string;
19
+ height: string;
20
+ transformOrigin: string;
21
+ transform: string;
22
+ };
23
+ getOriginStyle(): {
24
+ left: string;
25
+ top: string;
26
+ };
27
+ getSizerStyle(): {
28
+ width: string;
29
+ height: string;
30
+ };
31
+ onScroll(): void;
32
+ centerOnOrigin(): void;
33
+ scrollBy(dx: number, dy: number): void;
34
+ scrollToLocalPoint(pos: Point): void;
35
+ private setViewportScroll;
36
+ private updateViewportBox;
37
+ private getViewportSize;
38
+ private recalcCanvasMetrics;
39
+ }
@@ -0,0 +1,11 @@
1
+ import { CanvasSpace } from './CanvasSpace.js';
2
+ import { CanvasViewport } from './CanvasViewport.js';
3
+ export declare class CanvasZoom {
4
+ viewport: CanvasViewport;
5
+ space: CanvasSpace;
6
+ onWheel(ev: WheelEvent): void;
7
+ setZoom(newZoom: number): void;
8
+ zoomIn(): void;
9
+ zoomOut(): void;
10
+ private getClosestZoomStepIndex;
11
+ }
@@ -0,0 +1 @@
1
+ @layer nightshade-components{.CanvasBoxSelect[data-v-9e8905e1]{--CanvasBoxSelect-color:var(--canvas-box-select-color,var(--color-primary-500));--CanvasBoxSelect-opacity:var(--canvas-box-select-opacity,.1);z-index:20;pointer-events:none;position:absolute;inset:0}.Box[data-v-9e8905e1]{border:1px solid var(--CanvasBoxSelect-color);position:absolute}.Box[data-v-9e8905e1]:before{content:"";background:var(--CanvasBoxSelect-color);opacity:var(--CanvasBoxSelect-opacity);position:absolute;inset:0}.ResizeHandle[data-v-c83350e5]{--canvas-resize-handle-size:var(--sp2);--canvas-resize-handle-offset:calc(-.5 * var(--canvas-resize-handle-size));z-index:3;position:absolute}.ResizeHandle-n[data-v-c83350e5]{top:var(--canvas-resize-handle-offset);left:var(--canvas-resize-handle-offset);right:var(--canvas-resize-handle-offset);height:var(--canvas-resize-handle-size);cursor:ns-resize}.ResizeHandle-ne[data-v-c83350e5]{top:var(--canvas-resize-handle-offset);right:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);height:var(--canvas-resize-handle-size);cursor:nesw-resize;z-index:4}.ResizeHandle-e[data-v-c83350e5]{top:var(--canvas-resize-handle-offset);bottom:var(--canvas-resize-handle-offset);right:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);cursor:ew-resize}.ResizeHandle-se[data-v-c83350e5]{bottom:var(--canvas-resize-handle-offset);right:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);height:var(--canvas-resize-handle-size);cursor:nwse-resize;z-index:4}.ResizeHandle-s[data-v-c83350e5]{bottom:var(--canvas-resize-handle-offset);left:var(--canvas-resize-handle-offset);right:var(--canvas-resize-handle-offset);height:var(--canvas-resize-handle-size);cursor:ns-resize}.ResizeHandle-sw[data-v-c83350e5]{bottom:var(--canvas-resize-handle-offset);left:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);height:var(--canvas-resize-handle-size);cursor:nesw-resize;z-index:4}.ResizeHandle-w[data-v-c83350e5]{top:var(--canvas-resize-handle-offset);bottom:var(--canvas-resize-handle-offset);left:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);cursor:ew-resize}.ResizeHandle-nw[data-v-c83350e5]{top:var(--canvas-resize-handle-offset);left:var(--canvas-resize-handle-offset);width:var(--canvas-resize-handle-size);height:var(--canvas-resize-handle-size);cursor:nwse-resize;z-index:4}.CanvasView[data-v-52407cb1]{-webkit-user-select:none;user-select:none;display:flex;position:relative}.Viewport[data-v-52407cb1]{z-index:1;cursor:crosshair;flex:1;position:relative;overflow:auto}.Sizer[data-v-52407cb1]{z-index:0;position:relative}.Canvas[data-v-52407cb1]{position:absolute;top:0;left:0;overflow:hidden}.Origin[data-v-52407cb1]{position:absolute;transform:translate(-50%,-50%)}.DebugCoords[data-v-54d4bb42]{z-index:10;margin:var(--sp);padding:var(--sp);pointer-events:none;font-family:var(--font-monospace);font-size:var(--font-size-s);border:var(--input-border-size) solid var(--color-base-200);border-radius:var(--border-radius);background:var(--color-base-0);position:absolute;top:0;left:0}.Row[data-v-54d4bb42]{white-space:nowrap}}