mudlet-map-renderer 0.41.1-konva → 0.42.1-konva
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/CullingManager.d.ts +7 -70
- package/dist/InteractionHandler.d.ts +11 -29
- package/dist/ScenePipeline.d.ts +97 -32
- package/dist/camera/Camera.d.ts +106 -0
- package/dist/coord/CoordFn.d.ts +13 -0
- package/dist/draw/DrawCommand.d.ts +104 -0
- package/dist/draw/DrawCommandBuilder.d.ts +19 -0
- package/dist/export/CanvasExporter.d.ts +12 -8
- package/dist/export/Exporter.d.ts +5 -4
- package/dist/export/SvgExporter.d.ts +10 -6
- package/dist/export/clipSceneToViewport.d.ts +48 -0
- package/dist/export/flushSceneShapes.d.ts +21 -0
- package/dist/export/sceneBounds.d.ts +24 -0
- package/dist/hit/HitTester.d.ts +101 -0
- package/dist/index.d.ts +20 -10
- package/dist/index.mjs +3200 -2280
- package/dist/index.mjs.map +1 -1
- package/dist/overlay/AmbientLightOverlay.d.ts +2 -2
- package/dist/overlay/LiveEffect.d.ts +1 -1
- package/dist/overlay/SceneOverlay.d.ts +16 -11
- package/dist/render/CanvasRenderer.d.ts +17 -0
- package/dist/render/RecordingLayer.d.ts +158 -0
- package/dist/render/SvgRenderer.d.ts +7 -0
- package/dist/render/shapeToRecording.d.ts +3 -0
- package/dist/rendering/KonvaRenderBackend.d.ts +42 -39
- package/dist/rendering/MapRenderer.d.ts +65 -35
- package/dist/rendering/SceneManager.d.ts +53 -0
- package/dist/scene/Shape.d.ts +151 -0
- package/dist/scene/elements/ExitLayout.d.ts +22 -0
- package/dist/scene/elements/GridLayout.d.ts +24 -0
- package/dist/scene/elements/LabelLayout.d.ts +11 -0
- package/dist/scene/elements/OverlayLayout.d.ts +14 -0
- package/dist/scene/elements/RoomLayout.d.ts +19 -0
- package/dist/scene/elements/SpecialExitLayout.d.ts +19 -0
- package/dist/scene/elements/StubLayout.d.ts +19 -0
- package/dist/style/Style.d.ts +60 -0
- package/dist/style/applyStyle.d.ts +3 -0
- package/dist/style/index.d.ts +11 -22
- package/dist/style/shape/BlueprintStyle.d.ts +11 -0
- package/dist/style/shape/ConstructionStyle.d.ts +17 -0
- package/dist/style/shape/IsometricStyle.d.ts +32 -0
- package/dist/style/shape/NeonStyle.d.ts +17 -0
- package/dist/style/shape/ParchmentStyle.d.ts +13 -0
- package/dist/style/shape/SciFiStyle.d.ts +16 -0
- package/dist/style/shape/SketchyStyle.d.ts +22 -0
- package/dist/style/shape/index.d.ts +25 -0
- package/dist/style/shape/paintMap.d.ts +25 -0
- package/dist/style/shape/wobble.d.ts +24 -0
- package/dist/types/Settings.d.ts +0 -16
- package/package.json +2 -1
- package/dist/GridRenderer.d.ts +0 -21
- package/dist/RoomShapeRenderer.d.ts +0 -16
- package/dist/Viewport.d.ts +0 -87
- package/dist/backend/CanvasBackend.d.ts +0 -131
- package/dist/backend/DrawingBackend.d.ts +0 -184
- package/dist/backend/KonvaBackend.d.ts +0 -45
- package/dist/backend/SvgBackend.d.ts +0 -53
- package/dist/scene/OverlayRenderer.d.ts +0 -35
- package/dist/style/BlueprintStyle.d.ts +0 -26
- package/dist/style/IsometricStyle.d.ts +0 -71
- package/dist/style/NeonStyle.d.ts +0 -25
- package/dist/style/ParchmentStyle.d.ts +0 -40
- package/dist/style/SketchyStyle.d.ts +0 -33
package/dist/CullingManager.d.ts
CHANGED
|
@@ -1,78 +1,15 @@
|
|
|
1
1
|
import { Settings } from './types/Settings';
|
|
2
|
-
import {
|
|
3
|
-
export type CoordinateTransform = (x: number, y: number) => {
|
|
4
|
-
x: number;
|
|
5
|
-
y: number;
|
|
6
|
-
};
|
|
7
|
-
export type RoomNodeEntry = {
|
|
8
|
-
room: MapData.Room;
|
|
9
|
-
group: GroupNode;
|
|
10
|
-
};
|
|
11
|
-
type Bounds = {
|
|
12
|
-
x: number;
|
|
13
|
-
y: number;
|
|
14
|
-
width: number;
|
|
15
|
-
height: number;
|
|
16
|
-
};
|
|
17
|
-
export type StandaloneExitEntry = {
|
|
18
|
-
group: GroupNode;
|
|
19
|
-
bounds: Bounds;
|
|
20
|
-
targetRoomId?: number;
|
|
21
|
-
};
|
|
22
|
-
export type StageInfo = {
|
|
23
|
-
scaleX(): number;
|
|
24
|
-
position(): {
|
|
25
|
-
x: number;
|
|
26
|
-
y: number;
|
|
27
|
-
};
|
|
28
|
-
width(): number;
|
|
29
|
-
height(): number;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Manages spatial indexing and viewport culling for rooms and exits.
|
|
33
|
-
* Toggles node visibility based on what's in the viewport.
|
|
34
|
-
* No direct Konva dependency.
|
|
35
|
-
*/
|
|
2
|
+
import { CoordFn } from './coord/CoordFn';
|
|
36
3
|
export declare class CullingManager {
|
|
37
|
-
private readonly stageInfo;
|
|
38
|
-
private readonly roomLayer;
|
|
39
|
-
private readonly linkLayer;
|
|
40
4
|
private readonly settings;
|
|
41
|
-
|
|
42
|
-
standaloneExitNodes: StandaloneExitEntry[];
|
|
43
|
-
spatialBucketSize: number;
|
|
44
|
-
private roomSpatialIndex;
|
|
45
|
-
private exitSpatialIndex;
|
|
46
|
-
private visibleRooms;
|
|
47
|
-
private visibleStandaloneExitNodes;
|
|
48
|
-
private bufferRoomSet;
|
|
49
|
-
private bufferExitSet;
|
|
50
|
-
private bufferRoomCandidates;
|
|
51
|
-
private bufferExitCandidates;
|
|
52
|
-
private standaloneExitBoundsRoomSize?;
|
|
5
|
+
private readonly onCullingNeeded;
|
|
53
6
|
private cullingScheduled;
|
|
54
|
-
private perfMonitor;
|
|
55
7
|
private coordinateTransform;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
private transformPoint;
|
|
61
|
-
private transformBounds;
|
|
62
|
-
computeBucketSize(): void;
|
|
63
|
-
clear(): void;
|
|
64
|
-
private getBucketKey;
|
|
65
|
-
private forEachBucket;
|
|
66
|
-
addRoomToSpatialIndex(entry: RoomNodeEntry): void;
|
|
67
|
-
addStandaloneExitToSpatialIndex(entry: StandaloneExitEntry): void;
|
|
68
|
-
findRoomAtMapPoint(mapX: number, mapY: number): MapData.Room | null;
|
|
69
|
-
markExitBoundsStale(): void;
|
|
70
|
-
setExitBoundsRoomSize(): void;
|
|
71
|
-
private collectRoomCandidates;
|
|
72
|
-
private collectStandaloneExitCandidates;
|
|
73
|
-
private refreshStandaloneExitBoundsIfNeeded;
|
|
8
|
+
constructor(settings: Settings, onCullingNeeded: () => void);
|
|
9
|
+
setCoordinateTransform(fn: CoordFn): void;
|
|
10
|
+
getCoordinateTransform(): CoordFn;
|
|
11
|
+
/** Schedule a cull pass on the next animation frame (no-op if already scheduled). */
|
|
74
12
|
scheduleCulling(): void;
|
|
13
|
+
/** Run a cull pass immediately (used when mode changes). */
|
|
75
14
|
updateCulling(): void;
|
|
76
|
-
private cullExits;
|
|
77
15
|
}
|
|
78
|
-
export {};
|
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RendererEventMap } from './types/Settings';
|
|
2
2
|
import { TypedEventEmitter } from './TypedEventEmitter';
|
|
3
|
-
import {
|
|
3
|
+
import { Camera } from './camera/Camera';
|
|
4
4
|
import { MapState } from './MapState';
|
|
5
|
-
|
|
6
|
-
x: number;
|
|
7
|
-
y: number;
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
};
|
|
11
|
-
type AreaExitHitZone = {
|
|
12
|
-
bounds: Bounds;
|
|
13
|
-
targetRoomId: number;
|
|
14
|
-
};
|
|
5
|
+
import { HitResult } from './hit/HitTester';
|
|
15
6
|
export type HitTestCallbacks = {
|
|
16
7
|
clientToMapPoint: (clientX: number, clientY: number) => {
|
|
17
8
|
x: number;
|
|
18
9
|
y: number;
|
|
19
10
|
} | null;
|
|
20
|
-
findRoomAtPoint: (mapX: number, mapY: number) => MapData.Room | null;
|
|
21
|
-
getAreaExitHitZones: () => AreaExitHitZone[];
|
|
22
11
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* area-exit hit zones) under decorators like IsometricStyle.
|
|
12
|
+
* Pick the topmost hit-annotated shape at a point in rendered space. The
|
|
13
|
+
* unified entry point for all DOM-level interaction — rooms, area-exit
|
|
14
|
+
* labels, and any future pickable kinds all flow through one query.
|
|
27
15
|
*/
|
|
28
|
-
|
|
29
|
-
x: number;
|
|
30
|
-
y: number;
|
|
31
|
-
};
|
|
16
|
+
pickAtPoint: (renderedX: number, renderedY: number) => HitResult | null;
|
|
32
17
|
};
|
|
33
18
|
/**
|
|
34
19
|
* Handles all DOM interaction on the map container:
|
|
35
|
-
* -
|
|
20
|
+
* - Camera: drag (mouse + touch), wheel zoom, pinch zoom, resize
|
|
36
21
|
* - Map: hover cursor, click, right-click, long-press, area exit clicks
|
|
37
22
|
*
|
|
38
23
|
* No Konva dependency — works with any rendering backend.
|
|
39
24
|
*/
|
|
40
25
|
export declare class InteractionHandler {
|
|
41
26
|
private readonly container;
|
|
42
|
-
private readonly
|
|
43
|
-
private readonly viewport;
|
|
27
|
+
private readonly camera;
|
|
44
28
|
private readonly state;
|
|
45
29
|
private readonly hitTest;
|
|
46
30
|
private readonly events;
|
|
@@ -49,17 +33,15 @@ export declare class InteractionHandler {
|
|
|
49
33
|
private destroyed;
|
|
50
34
|
/** Skip cursor changes when an external consumer (e.g. the editor) owns cursor management. */
|
|
51
35
|
private setCursor;
|
|
52
|
-
constructor(container: HTMLDivElement,
|
|
36
|
+
constructor(container: HTMLDivElement, camera: Camera, state: MapState, hitTest: HitTestCallbacks, events: TypedEventEmitter<RendererEventMap>);
|
|
53
37
|
destroy(): void;
|
|
54
38
|
private listen;
|
|
55
39
|
private initViewportEvents;
|
|
56
40
|
private handlePinch;
|
|
57
41
|
private initMapEvents;
|
|
58
|
-
private
|
|
59
|
-
private findAreaExitAtClientPoint;
|
|
42
|
+
private pickAtClientPoint;
|
|
60
43
|
private emitRoomClickEvent;
|
|
61
44
|
private emitRoomContextEvent;
|
|
62
45
|
private emitAreaExitClickEvent;
|
|
63
46
|
private emitMapClickEvent;
|
|
64
47
|
}
|
|
65
|
-
export {};
|
package/dist/ScenePipeline.d.ts
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
import { default as MapReader } from './reader/MapReader';
|
|
2
2
|
import { default as Area } from './reader/Area';
|
|
3
3
|
import { default as Plane } from './reader/Plane';
|
|
4
|
-
import { Settings
|
|
5
|
-
import { DrawingBackend, GroupNode, LayerNode } from './backend/DrawingBackend';
|
|
6
|
-
import { RoomShapeRenderer } from './RoomShapeRenderer';
|
|
7
|
-
import { GridRenderer } from './GridRenderer';
|
|
4
|
+
import { Settings } from './types/Settings';
|
|
8
5
|
import { default as ExitRenderer, ExitDrawData } from './ExitRenderer';
|
|
6
|
+
import { GroupShape, Shape } from './scene/Shape';
|
|
9
7
|
type Bounds = {
|
|
10
8
|
x: number;
|
|
11
9
|
y: number;
|
|
12
10
|
width: number;
|
|
13
11
|
height: number;
|
|
14
12
|
};
|
|
15
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Reference to one room's body shape inside the scene. Keyed by roomId so
|
|
15
|
+
* downstream consumers (cull index, hit-test bookkeeping) can find a room
|
|
16
|
+
* shape by id without re-walking the scene tree.
|
|
17
|
+
*/
|
|
18
|
+
export type RoomShapeRef = {
|
|
16
19
|
room: MapData.Room;
|
|
17
|
-
|
|
20
|
+
shape: GroupShape;
|
|
18
21
|
};
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Reference to one drawn link-exit shape, paired with its world-space bounds
|
|
24
|
+
* and (optional) cross-area target room. Used by the live renderer to hang
|
|
25
|
+
* cull entries on each exit.
|
|
26
|
+
*/
|
|
27
|
+
export type StandaloneExitShapeRef = {
|
|
28
|
+
shape: GroupShape;
|
|
21
29
|
bounds: Bounds;
|
|
22
30
|
targetRoomId?: number;
|
|
23
31
|
};
|
|
@@ -91,44 +99,99 @@ export type DrawnStubEntry = {
|
|
|
91
99
|
readonly stroke: string;
|
|
92
100
|
readonly strokeWidth: number;
|
|
93
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* World-space shapes for each logical layer. Same content the backend layer
|
|
104
|
+
* nodes received, but as plain SceneIR data — consumed by exporters that drive
|
|
105
|
+
* {@link buildDrawCommands} → engine renderers without going through a
|
|
106
|
+
* {@link DrawingBackend}.
|
|
107
|
+
*
|
|
108
|
+
* Order within each list mirrors the order in which the corresponding layer
|
|
109
|
+
* node received its `addNode` calls: e.g. `link` is labels → link exits → for
|
|
110
|
+
* each room (special exits, stubs); `room` is rooms → area name → area-exit
|
|
111
|
+
* labels.
|
|
112
|
+
*/
|
|
113
|
+
export type SceneShapesByLayer = {
|
|
114
|
+
grid: Shape[];
|
|
115
|
+
link: Shape[];
|
|
116
|
+
room: Shape[];
|
|
117
|
+
topLabel: Shape[];
|
|
118
|
+
};
|
|
119
|
+
/** User-defined label shape paired with its world-space bounds (for culling). */
|
|
120
|
+
export type LabelShapeRef = {
|
|
121
|
+
shape: GroupShape;
|
|
122
|
+
bounds: Bounds;
|
|
123
|
+
};
|
|
124
|
+
/** Custom-line (special-exit) shape paired with its world-space bounds (for culling). */
|
|
125
|
+
export type SpecialExitShapeRef = {
|
|
126
|
+
shape: GroupShape;
|
|
127
|
+
bounds: Bounds;
|
|
128
|
+
};
|
|
129
|
+
/** Stub shape paired with its world-space bounds (for culling). */
|
|
130
|
+
export type StubShapeRef = {
|
|
131
|
+
shape: GroupShape;
|
|
132
|
+
bounds: Bounds;
|
|
133
|
+
};
|
|
134
|
+
/** Area-exit label shape paired with its world-space bounds (for culling). */
|
|
135
|
+
export type AreaExitLabelShapeRef = {
|
|
136
|
+
shape: GroupShape;
|
|
137
|
+
bounds: Bounds;
|
|
138
|
+
};
|
|
94
139
|
export type SceneBuildResult = {
|
|
95
|
-
|
|
96
|
-
|
|
140
|
+
/** Room body shapes keyed by roomId — for cull-entry construction. */
|
|
141
|
+
roomShapeRefs: Map<number, RoomShapeRef>;
|
|
142
|
+
/** Link-exit shapes paired with bounds and area-target metadata. */
|
|
143
|
+
standaloneExitShapeRefs: StandaloneExitShapeRef[];
|
|
144
|
+
/** Non-noScaling label shapes paired with world-space bounds (for culling). */
|
|
145
|
+
labelShapeRefs: LabelShapeRef[];
|
|
146
|
+
/** Custom-line special-exit shapes paired with world-space bounds (for culling). */
|
|
147
|
+
specialExitShapeRefs: SpecialExitShapeRef[];
|
|
148
|
+
/** Stub shapes paired with world-space bounds (for culling). */
|
|
149
|
+
stubShapeRefs: StubShapeRef[];
|
|
150
|
+
/** Area-exit label shapes paired with world-space bounds (for culling). */
|
|
151
|
+
areaExitLabelShapeRefs: AreaExitLabelShapeRef[];
|
|
97
152
|
areaExitHitZones: AreaExitHitZone[];
|
|
98
153
|
drawnExits: DrawnExitEntry[];
|
|
99
154
|
drawnSpecialExits: DrawnSpecialExitEntry[];
|
|
100
155
|
drawnStubs: DrawnStubEntry[];
|
|
156
|
+
/** World-space shapes carrying {@link HitInfo} annotations — fed to {@link HitTester}. */
|
|
157
|
+
hitShapes: Shape[];
|
|
158
|
+
/**
|
|
159
|
+
* Engine-agnostic shape lists per logical layer. Drives
|
|
160
|
+
* {@link buildDrawCommands} + a per-engine renderer.
|
|
161
|
+
*/
|
|
162
|
+
sceneShapes: SceneShapesByLayer;
|
|
101
163
|
};
|
|
102
164
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
165
|
+
* Engine-neutral scene composition pipeline.
|
|
166
|
+
*
|
|
167
|
+
* Walks a {@link MapData} area/plane and emits world-space {@link Shape}s per
|
|
168
|
+
* logical layer (grid / link / room / topLabel) plus the metadata downstream
|
|
169
|
+
* consumers need (cull entries, hit zones, drawn-geometry snapshots).
|
|
105
170
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
171
|
+
* The pipeline knows nothing about Konva, SVG, Canvas, or the
|
|
172
|
+
* {@link DrawCommandBuilder}: callers run the shape lists through whatever
|
|
173
|
+
* renderer fits their target. Both the interactive
|
|
174
|
+
* {@link KonvaRenderBackend} and the exporters consume the same
|
|
175
|
+
* {@link SceneBuildResult} this pipeline produces.
|
|
108
176
|
*/
|
|
109
177
|
export declare class ScenePipeline {
|
|
110
178
|
private readonly mapReader;
|
|
111
179
|
private readonly settings;
|
|
112
|
-
private readonly backend;
|
|
113
|
-
readonly roomShapeRenderer: RoomShapeRenderer;
|
|
114
|
-
readonly gridRenderer: GridRenderer;
|
|
115
180
|
readonly exitRenderer: ExitRenderer;
|
|
116
|
-
private
|
|
117
|
-
private
|
|
118
|
-
private
|
|
119
|
-
private
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
topLabelLayer?: LayerNode;
|
|
125
|
-
});
|
|
181
|
+
private linkShapes;
|
|
182
|
+
private roomShapes;
|
|
183
|
+
private topLabelShapes;
|
|
184
|
+
private labelShapeRefs;
|
|
185
|
+
private specialExitShapeRefs;
|
|
186
|
+
private stubShapeRefs;
|
|
187
|
+
private areaExitLabelShapeRefs;
|
|
188
|
+
constructor(mapReader: MapReader, settings: Settings);
|
|
126
189
|
/**
|
|
127
190
|
* Build the full scene for an area/plane.
|
|
128
191
|
* Clears layers, renders grid → labels → exits → rooms → area name.
|
|
129
192
|
* Returns data for culling and interaction (room nodes, exit data, hit zones).
|
|
130
193
|
*/
|
|
131
|
-
buildScene(area: Area, plane: Plane, zIndex: number
|
|
194
|
+
buildScene(area: Area, plane: Plane, zIndex: number): SceneBuildResult;
|
|
132
195
|
getEffectiveBounds(area: Area, plane: Plane): {
|
|
133
196
|
minX: number;
|
|
134
197
|
maxX: number;
|
|
@@ -137,10 +200,12 @@ export declare class ScenePipeline {
|
|
|
137
200
|
};
|
|
138
201
|
private renderRooms;
|
|
139
202
|
private renderLinkExits;
|
|
140
|
-
/**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Build the world-space shape tree for one inter-room exit. Used by the
|
|
205
|
+
* live renderer's current-room overlay path to recolour a single exit
|
|
206
|
+
* without rebuilding the whole scene.
|
|
207
|
+
*/
|
|
208
|
+
buildExitShape(data: ExitDrawData): GroupShape;
|
|
144
209
|
private renderLabels;
|
|
145
210
|
private renderAreaExitLabels;
|
|
146
211
|
private renderAreaName;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ViewportBounds } from '../types/Settings';
|
|
2
|
+
import { TypedEventEmitter } from '../TypedEventEmitter';
|
|
3
|
+
/** Pixels-per-world-unit at zoom = 1. Multiply by `Camera.zoom` for actual scale. */
|
|
4
|
+
export declare const BASE_SCALE = 75;
|
|
5
|
+
/** Events fired by {@link Camera}. */
|
|
6
|
+
export type CameraEventMap = {
|
|
7
|
+
/** Any state change: zoom, pan, size, animation tick. */
|
|
8
|
+
change: void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Engine-agnostic camera — owns transform state, drag, and animation.
|
|
12
|
+
*
|
|
13
|
+
* Subscribers ({@link KonvaRenderer}, {@link CullingManager}, {@link HitTester},
|
|
14
|
+
* scene overlays) listen to the `change` event to react to view updates.
|
|
15
|
+
*
|
|
16
|
+
* No Konva, no DOM. Only dependency is requestAnimationFrame (with a
|
|
17
|
+
* setTimeout fallback for Node.js).
|
|
18
|
+
*/
|
|
19
|
+
export declare class Camera extends TypedEventEmitter<CameraEventMap> {
|
|
20
|
+
zoom: number;
|
|
21
|
+
minZoom: number;
|
|
22
|
+
position: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
};
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
/** When true, resizing re-centers on the last panToMapPoint target. */
|
|
29
|
+
centerOnResize: boolean;
|
|
30
|
+
private dragging;
|
|
31
|
+
private dragStart;
|
|
32
|
+
private positionAtDragStart;
|
|
33
|
+
private animationId?;
|
|
34
|
+
constructor(width: number, height: number);
|
|
35
|
+
getScale(): number;
|
|
36
|
+
setZoom(zoom: number): boolean;
|
|
37
|
+
/** Zoom keeping the center of the viewport fixed. */
|
|
38
|
+
zoomToCenter(zoom: number): boolean;
|
|
39
|
+
/** Zoom keeping a specific screen point fixed (for mouse wheel zoom). */
|
|
40
|
+
zoomToPoint(zoom: number, screenX: number, screenY: number): boolean;
|
|
41
|
+
/** Bounds of the visible area in map space. */
|
|
42
|
+
getViewportBounds(): ViewportBounds;
|
|
43
|
+
/**
|
|
44
|
+
* Map-space bounds to use for culling. When `cullingBounds` is a
|
|
45
|
+
* screen-pixel sub-rect it is converted to map space via the current
|
|
46
|
+
* camera transform; otherwise the full viewport is returned.
|
|
47
|
+
*/
|
|
48
|
+
getCullingViewport(cullingBounds?: {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
} | null): ViewportBounds;
|
|
54
|
+
/**
|
|
55
|
+
* Create a Camera whose full viewport covers exactly the given world-space bounds.
|
|
56
|
+
* Used by headless exporters that need a Camera but have no real display.
|
|
57
|
+
*/
|
|
58
|
+
static forMapBounds(minX: number, maxX: number, minY: number, maxY: number): Camera;
|
|
59
|
+
/**
|
|
60
|
+
* Create a Camera from an explicit render-camera transform (scale + offset).
|
|
61
|
+
* Used by {@link CanvasExporter} to derive culling bounds from the already-
|
|
62
|
+
* computed fitted transform without re-doing the letterbox math.
|
|
63
|
+
*/
|
|
64
|
+
static forRenderCamera(width: number, height: number, scale: number, offsetX: number, offsetY: number): Camera;
|
|
65
|
+
/** Convert client/screen coordinates to map coordinates. */
|
|
66
|
+
clientToMapPoint(clientX: number, clientY: number, containerOffset?: {
|
|
67
|
+
left: number;
|
|
68
|
+
top: number;
|
|
69
|
+
}): {
|
|
70
|
+
x: number;
|
|
71
|
+
y: number;
|
|
72
|
+
} | null;
|
|
73
|
+
/** Center on a map coordinate, instantly. */
|
|
74
|
+
panToMapPoint(x: number, y: number): void;
|
|
75
|
+
/** Center on a map coordinate, with optional animation. */
|
|
76
|
+
panToMapPointAnimated(x: number, y: number, instant: boolean): void;
|
|
77
|
+
/**
|
|
78
|
+
* Compute the zoom level that would fit the given map bounds in the current
|
|
79
|
+
* viewport (with the same padding/insets as {@link fitToMapBounds}).
|
|
80
|
+
*/
|
|
81
|
+
computeFitZoom(minX: number, maxX: number, minY: number, maxY: number, insets?: {
|
|
82
|
+
top?: number;
|
|
83
|
+
right?: number;
|
|
84
|
+
bottom?: number;
|
|
85
|
+
left?: number;
|
|
86
|
+
}): number;
|
|
87
|
+
/**
|
|
88
|
+
* Fit the camera to show the given map bounds with padding.
|
|
89
|
+
* Optional `insets` (screen pixels) reserve space at each edge.
|
|
90
|
+
*/
|
|
91
|
+
fitToMapBounds(minX: number, maxX: number, minY: number, maxY: number, insets?: {
|
|
92
|
+
top?: number;
|
|
93
|
+
right?: number;
|
|
94
|
+
bottom?: number;
|
|
95
|
+
left?: number;
|
|
96
|
+
}): void;
|
|
97
|
+
setSize(width: number, height: number): void;
|
|
98
|
+
startDrag(screenX: number, screenY: number): void;
|
|
99
|
+
updateDrag(screenX: number, screenY: number): void;
|
|
100
|
+
endDrag(): void;
|
|
101
|
+
isDragging(): boolean;
|
|
102
|
+
private animate;
|
|
103
|
+
cancelAnimation(): void;
|
|
104
|
+
isAnimating(): boolean;
|
|
105
|
+
private notify;
|
|
106
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forward / inverse 2D coordinate transform. Used by camera-aware code that
|
|
3
|
+
* needs to translate between world space (the map's flat XY) and scene space
|
|
4
|
+
* (whatever the active style projects into — e.g. an isometric diamond).
|
|
5
|
+
*
|
|
6
|
+
* `IDENTITY_TRANSFORM` returns the input unchanged; flat styles (Parchment,
|
|
7
|
+
* Sketchy, plain identity) use it for both the forward and inverse direction.
|
|
8
|
+
*/
|
|
9
|
+
export type CoordFn = (x: number, y: number) => {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
export declare const IDENTITY_TRANSFORM: CoordFn;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { LayerId } from '../scene/Shape';
|
|
2
|
+
export interface RectCommand {
|
|
3
|
+
type: "rect";
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
w: number;
|
|
7
|
+
h: number;
|
|
8
|
+
fill?: string;
|
|
9
|
+
stroke?: string;
|
|
10
|
+
/** Stroke width in render units. */
|
|
11
|
+
sw: number;
|
|
12
|
+
/** Corner radius in render units. */
|
|
13
|
+
cr: number;
|
|
14
|
+
dash?: number[];
|
|
15
|
+
}
|
|
16
|
+
export interface CircleCommand {
|
|
17
|
+
type: "circle";
|
|
18
|
+
cx: number;
|
|
19
|
+
cy: number;
|
|
20
|
+
r: number;
|
|
21
|
+
fill?: string;
|
|
22
|
+
stroke?: string;
|
|
23
|
+
sw: number;
|
|
24
|
+
dash?: number[];
|
|
25
|
+
}
|
|
26
|
+
export interface LineCommand {
|
|
27
|
+
type: "line";
|
|
28
|
+
/** Flat list of [x0, y0, x1, y1, …] in render space. */
|
|
29
|
+
points: number[];
|
|
30
|
+
stroke?: string;
|
|
31
|
+
sw: number;
|
|
32
|
+
dash?: number[];
|
|
33
|
+
lineCap?: "butt" | "round" | "square";
|
|
34
|
+
lineJoin?: "miter" | "round" | "bevel";
|
|
35
|
+
/** 0..1 multiplier. */
|
|
36
|
+
alpha?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface PolygonCommand {
|
|
39
|
+
type: "polygon";
|
|
40
|
+
vertices: number[];
|
|
41
|
+
fill?: string;
|
|
42
|
+
stroke?: string;
|
|
43
|
+
sw: number;
|
|
44
|
+
}
|
|
45
|
+
export interface TextCommand {
|
|
46
|
+
type: "text";
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
text: string;
|
|
50
|
+
fontSize: number;
|
|
51
|
+
fontFamily: string;
|
|
52
|
+
fontStyle: string;
|
|
53
|
+
fill: string;
|
|
54
|
+
stroke?: string;
|
|
55
|
+
/** Stroke width in render units (0 = no stroke). */
|
|
56
|
+
sw: number;
|
|
57
|
+
align: "left" | "center" | "right";
|
|
58
|
+
vAlign: "top" | "middle" | "bottom";
|
|
59
|
+
w: number;
|
|
60
|
+
h: number;
|
|
61
|
+
baselineRatio?: number;
|
|
62
|
+
konvaCorrectionRatio?: number;
|
|
63
|
+
transform?: [number, number, number, number, number, number];
|
|
64
|
+
}
|
|
65
|
+
export interface ImageCommand {
|
|
66
|
+
type: "image";
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
w: number;
|
|
70
|
+
h: number;
|
|
71
|
+
src: string;
|
|
72
|
+
transform?: [number, number, number, number, number, number];
|
|
73
|
+
}
|
|
74
|
+
/** Push an affine transform [a, b, c, d, e, f] onto the renderer's stack. */
|
|
75
|
+
export interface PushTransformCommand {
|
|
76
|
+
type: "pushTransform";
|
|
77
|
+
matrix: [number, number, number, number, number, number];
|
|
78
|
+
}
|
|
79
|
+
/** Pop the most recent transform. */
|
|
80
|
+
export interface PopTransformCommand {
|
|
81
|
+
type: "popTransform";
|
|
82
|
+
}
|
|
83
|
+
/** Push a clip rect; subsequent draws are clipped until matching pop. */
|
|
84
|
+
export interface PushClipCommand {
|
|
85
|
+
type: "pushClip";
|
|
86
|
+
x: number;
|
|
87
|
+
y: number;
|
|
88
|
+
w: number;
|
|
89
|
+
h: number;
|
|
90
|
+
}
|
|
91
|
+
export interface PopClipCommand {
|
|
92
|
+
type: "popClip";
|
|
93
|
+
}
|
|
94
|
+
export type PrimitiveDrawCommand = RectCommand | CircleCommand | LineCommand | PolygonCommand | TextCommand | ImageCommand;
|
|
95
|
+
export type StackDrawCommand = PushTransformCommand | PopTransformCommand | PushClipCommand | PopClipCommand;
|
|
96
|
+
export type DrawCommand = PrimitiveDrawCommand | StackDrawCommand;
|
|
97
|
+
/**
|
|
98
|
+
* A bundle of commands targeting one logical layer. Renderers iterate layers
|
|
99
|
+
* in z-order and flush commands per layer.
|
|
100
|
+
*/
|
|
101
|
+
export interface DrawCommandBatch {
|
|
102
|
+
layer: LayerId;
|
|
103
|
+
commands: DrawCommand[];
|
|
104
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DrawCommandBatch } from './DrawCommand';
|
|
2
|
+
import { Shape } from '../scene/Shape';
|
|
3
|
+
/** Camera state needed to project world coordinates into render space. */
|
|
4
|
+
export interface CameraTransform {
|
|
5
|
+
/** Pixels per world unit. */
|
|
6
|
+
scale: number;
|
|
7
|
+
/** Render-space origin in pixels. */
|
|
8
|
+
offsetX: number;
|
|
9
|
+
offsetY: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build per-layer {@link DrawCommandBatch}es from a list of world-space shapes
|
|
13
|
+
* and an active camera transform.
|
|
14
|
+
*
|
|
15
|
+
* Layer order in the result follows first-appearance order; renderers iterate
|
|
16
|
+
* the array as-is (z-order is the caller's responsibility — typically scene
|
|
17
|
+
* layout uses the LayerId taxonomy to pre-sort).
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildDrawCommands(shapes: Shape[], camera: CameraTransform): DrawCommandBatch[];
|
|
@@ -24,20 +24,23 @@ export interface CanvasExportOptions {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Renders the current scene into a canvas at the requested width/height
|
|
28
|
-
*
|
|
27
|
+
* Renders the current scene into a canvas at the requested width/height by
|
|
28
|
+
* driving {@link ScenePipeline} → {@link buildDrawCommands} →
|
|
29
|
+
* {@link renderToCanvas}.
|
|
29
30
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* Decoupled from the live Konva stage: the pipeline is rebuilt against the
|
|
32
|
+
* export bounds, shapes are projected through a fitted camera transform, and
|
|
33
|
+
* the result is rasterized onto a fresh 2D canvas. Background colour is
|
|
34
|
+
* filled before any draw commands replay, so PNG / JPEG output looks identical
|
|
35
|
+
* to the on-screen map.
|
|
33
36
|
*
|
|
34
|
-
* Unlike {@link PngExporter} (which
|
|
35
|
-
* `CanvasExporter` is
|
|
37
|
+
* Unlike {@link PngExporter} (which captures the on-screen viewport via the
|
|
38
|
+
* live Konva stage), `CanvasExporter` is fully headless and reproducible.
|
|
36
39
|
*/
|
|
37
40
|
export declare class CanvasExporter implements Exporter<ExportCanvas | undefined> {
|
|
38
41
|
private readonly options;
|
|
39
42
|
constructor(options: CanvasExportOptions);
|
|
40
|
-
render({
|
|
43
|
+
render({ state, style, sceneOverlays }: ExportContext): ExportCanvas | undefined;
|
|
41
44
|
}
|
|
42
45
|
export interface PngBytesExportOptions extends CanvasExportOptions {
|
|
43
46
|
/** MIME type to encode. Defaults to `'image/png'`. */
|
|
@@ -62,6 +65,7 @@ export interface PngBytesExportOptions extends CanvasExportOptions {
|
|
|
62
65
|
*/
|
|
63
66
|
export declare class PngBytesExporter implements Exporter<Uint8Array | undefined> {
|
|
64
67
|
private readonly options;
|
|
68
|
+
private readonly canvasExporter;
|
|
65
69
|
constructor(options: PngBytesExportOptions);
|
|
66
70
|
render(context: ExportContext): Uint8Array | undefined;
|
|
67
71
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MapState } from '../MapState';
|
|
2
|
-
import { Style } from '../
|
|
2
|
+
import { Style } from '../style/Style';
|
|
3
3
|
import { SceneOverlay } from '../overlay/SceneOverlay';
|
|
4
4
|
import { InteractiveBackend } from '../rendering/MapRenderer';
|
|
5
5
|
/**
|
|
@@ -31,9 +31,10 @@ export interface Exporter<T> {
|
|
|
31
31
|
render(context: ExportContext): T;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* Canvas returned by {@link
|
|
35
|
-
* {@link
|
|
36
|
-
* browser `HTMLCanvasElement` and the `canvas` package's
|
|
34
|
+
* Canvas returned by {@link CanvasExporter} and
|
|
35
|
+
* {@link InteractiveBackend.exportCanvas}. Describes the portable surface
|
|
36
|
+
* common to the browser `HTMLCanvasElement` and the `canvas` package's
|
|
37
|
+
* Node-side Canvas:
|
|
37
38
|
*
|
|
38
39
|
* - Portable: `width`, `height`, `getContext`, `toDataURL`.
|
|
39
40
|
* - Browser: `toBlob(cb)` (optional here; use when serializing to a Blob).
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { SvgExportOptions } from '../SvgTypes';
|
|
2
2
|
import { Exporter, ExportContext } from './Exporter';
|
|
3
3
|
/**
|
|
4
|
-
* Renders the current scene as an SVG string
|
|
5
|
-
* {@link ScenePipeline}
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Renders the current scene as an SVG string by driving
|
|
5
|
+
* {@link ScenePipeline} → {@link buildDrawCommands} → {@link svgFromBatches}.
|
|
6
|
+
*
|
|
7
|
+
* The pipeline is rebuilt with bounded viewport bounds (so the grid layout
|
|
8
|
+
* matches the export region), then `sceneShapes` is flushed through the
|
|
9
|
+
* draw-command pipeline at scale 1 — coordinates land inside the SVG
|
|
10
|
+
* viewBox in world space, identical to the legacy SvgBackend output. Active
|
|
11
|
+
* {@link SceneOverlay}s are still rendered against an {@link SvgBackend}
|
|
12
|
+
* so user code that builds custom overlays via the DrawingBackend keeps
|
|
13
|
+
* working until the overlay API is migrated to shapes.
|
|
9
14
|
*/
|
|
10
15
|
export declare class SvgExporter implements Exporter<string | undefined> {
|
|
11
16
|
private readonly options;
|
|
12
17
|
constructor(options?: SvgExportOptions);
|
|
13
18
|
render({ state, style, sceneOverlays }: ExportContext): string | undefined;
|
|
14
|
-
private renderBuiltInOverlays;
|
|
15
19
|
}
|