mudlet-map-renderer 1.0.0 → 1.2.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/README.md +520 -0
- package/dist/AreaMapRenderer.d.ts +125 -0
- package/dist/CullingManager.d.ts +15 -0
- package/dist/ExitRenderer.d.ts +109 -0
- package/dist/InteractionHandler.d.ts +47 -0
- package/dist/MapGraph.d.ts +28 -0
- package/dist/MapReader-mU_4JWv_.js +224 -0
- package/dist/MapReader-mU_4JWv_.js.map +1 -0
- package/dist/MapState.d.ts +110 -0
- package/dist/PathData.d.ts +18 -0
- package/dist/PathFinder.d.ts +12 -0
- package/dist/ScenePipeline.d.ts +226 -0
- package/dist/SvgTypes.d.ts +21 -0
- package/dist/TypedEventEmitter.d.ts +17 -0
- package/dist/binary/BinaryMapReader.d.ts +36 -0
- package/dist/binary/index.d.ts +2 -0
- package/dist/binary.mjs +34 -0
- package/dist/binary.mjs.map +1 -0
- package/dist/camera/Camera.d.ts +118 -0
- package/dist/coord/CoordFn.d.ts +13 -0
- package/dist/directions.d.ts +25 -0
- package/dist/draw/DrawCommand.d.ts +104 -0
- package/dist/draw/DrawCommandBuilder.d.ts +19 -0
- package/dist/export/CanvasExporter.d.ts +71 -0
- package/dist/export/Exporter.d.ts +58 -0
- package/dist/export/PngExporter.d.ts +23 -0
- package/dist/export/SvgExporter.d.ts +19 -0
- package/dist/export/canvasToBytes.d.ts +19 -0
- 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 +61 -0
- package/dist/index.mjs +6670 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lens/ExplorationLens.d.ts +29 -0
- package/dist/lens/RoomLens.d.ts +47 -0
- package/dist/lens/composeLenses.d.ts +31 -0
- package/dist/lens/index.d.ts +5 -0
- package/dist/overlay/AmbientLightOverlay.d.ts +32 -0
- package/dist/overlay/LiveEffect.d.ts +33 -0
- package/dist/overlay/SceneOverlay.d.ts +68 -0
- package/dist/reader/Area.d.ts +63 -0
- package/dist/reader/Exit.d.ts +15 -0
- package/dist/reader/MapReader.d.ts +34 -0
- package/dist/reader/Plane.d.ts +33 -0
- 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 +122 -0
- package/dist/rendering/MapRenderer.d.ts +213 -0
- package/dist/rendering/SceneManager.d.ts +54 -0
- package/dist/scene/AmbientLightStyle.d.ts +29 -0
- package/dist/scene/GridStyle.d.ts +21 -0
- package/dist/scene/InnerExitStyle.d.ts +24 -0
- package/dist/scene/OverlayStyle.d.ts +47 -0
- package/dist/scene/RoomStyle.d.ts +32 -0
- package/dist/scene/Shape.d.ts +151 -0
- package/dist/scene/SpecialExitStyle.d.ts +37 -0
- package/dist/scene/StubStyle.d.ts +15 -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 +21 -0
- 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/{src/types/MapData.ts → dist/types/MapData.d.ts} +70 -90
- package/dist/types/Settings.d.ts +206 -0
- package/dist/utils/color.d.ts +12 -0
- package/dist/utils/textMeasure.d.ts +38 -0
- package/package.json +67 -37
- package/demo/colors.json +0 -1
- package/demo/index.html +0 -102
- package/demo/main.ts +0 -389
- package/demo/mapExport.json +0 -1
- package/demo/tsconfig.json +0 -11
- package/src/ExitRenderer.ts +0 -275
- package/src/PathFinder.ts +0 -93
- package/src/PathRenderer.ts +0 -129
- package/src/Renderer.ts +0 -374
- package/src/directions.ts +0 -66
- package/src/index.ts +0 -4
- package/src/reader/Area.ts +0 -96
- package/src/reader/Exit.ts +0 -36
- package/src/reader/ExplorationArea.ts +0 -132
- package/src/reader/MapReader.ts +0 -123
- package/src/reader/Plane.ts +0 -42
- package/tsconfig.json +0 -17
- package/vercel.json +0 -5
- package/vite.config.ts +0 -29
- package/vite.demo.config.ts +0 -15
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { IMapReader } from './reader/MapReader';
|
|
2
|
+
import { IArea } from './reader/Area';
|
|
3
|
+
import { IPlane } from './reader/Plane';
|
|
4
|
+
import { Settings } from './types/Settings';
|
|
5
|
+
import { default as ExitRenderer, ExitDrawData } from './ExitRenderer';
|
|
6
|
+
import { GroupShape, Shape } from './scene/Shape';
|
|
7
|
+
import { RoomLens } from './lens/RoomLens';
|
|
8
|
+
type Bounds = {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Reference to one room's body shape inside the scene. Keyed by roomId so
|
|
16
|
+
* downstream consumers (cull index, hit-test bookkeeping) can find a room
|
|
17
|
+
* shape by id without re-walking the scene tree.
|
|
18
|
+
*/
|
|
19
|
+
export type RoomShapeRef = {
|
|
20
|
+
room: MapData.Room;
|
|
21
|
+
shape: GroupShape;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Reference to one drawn link-exit shape, paired with its world-space bounds
|
|
25
|
+
* and (optional) cross-area target room. Used by the live renderer to hang
|
|
26
|
+
* cull entries on each exit.
|
|
27
|
+
*/
|
|
28
|
+
export type StandaloneExitShapeRef = {
|
|
29
|
+
shape: GroupShape;
|
|
30
|
+
bounds: Bounds;
|
|
31
|
+
targetRoomId?: number;
|
|
32
|
+
};
|
|
33
|
+
export type AreaExitHitZone = {
|
|
34
|
+
bounds: Bounds;
|
|
35
|
+
targetRoomId: number;
|
|
36
|
+
/** Source room center — used to compute arrow direction for labels. Optional for back-compat. */
|
|
37
|
+
from?: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
};
|
|
41
|
+
/** Arrow tip / far endpoint — anchor for placed labels. Optional for back-compat. */
|
|
42
|
+
tip?: {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
};
|
|
46
|
+
/** Stroke colour of the rendered arrow — used to colour area-exit labels. */
|
|
47
|
+
arrowColor?: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* One drawn two-way or one-way inter-room exit, with stable identity and the
|
|
51
|
+
* exact geometry ExitRenderer produced. Consumers (e.g. an editor's
|
|
52
|
+
* hit-testing layer) can run segment distance checks against
|
|
53
|
+
* `data.lines[].points` / `data.arrows[].points` to match exactly what the
|
|
54
|
+
* user sees — including dash patterns and the renderer's suppression rules
|
|
55
|
+
* (e.g. both-sides-customLine two-ways, one-ways overridden by customLine).
|
|
56
|
+
*/
|
|
57
|
+
export type DrawnExitEntry = {
|
|
58
|
+
readonly a: number;
|
|
59
|
+
readonly b: number;
|
|
60
|
+
readonly aDir?: MapData.direction;
|
|
61
|
+
readonly bDir?: MapData.direction;
|
|
62
|
+
readonly kind: "exit" | "specialExit";
|
|
63
|
+
readonly zIndex: number[];
|
|
64
|
+
readonly data: ExitDrawData;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* One drawn custom-line (special exit) polyline, as it was rendered for
|
|
68
|
+
* this scene. `points` is the flat [x,y,x,y,...] polyline with the source
|
|
69
|
+
* room's centre prepended (mirroring what the renderer actually drew), in
|
|
70
|
+
* render-space coordinates.
|
|
71
|
+
*/
|
|
72
|
+
export type DrawnSpecialExitEntry = {
|
|
73
|
+
readonly roomId: number;
|
|
74
|
+
readonly exitName: string;
|
|
75
|
+
readonly points: number[];
|
|
76
|
+
readonly stroke: string;
|
|
77
|
+
readonly strokeWidth: number;
|
|
78
|
+
readonly dash?: number[];
|
|
79
|
+
readonly hasArrow: boolean;
|
|
80
|
+
readonly arrowTip?: {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
};
|
|
84
|
+
readonly bounds: Bounds;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* One drawn stub — a room's one-way exit indicator (the short line sticking
|
|
88
|
+
* out of the edge for every entry in `room.stubs`). Rendered directly from
|
|
89
|
+
* these coordinates by {@link ScenePipeline}, so hit-testing against them
|
|
90
|
+
* matches what's on screen. Non-planar stubs (up/down/in/out) are still
|
|
91
|
+
* recorded — x1==x2 and y1==y2 — so consumers can filter them out.
|
|
92
|
+
*/
|
|
93
|
+
export type DrawnStubEntry = {
|
|
94
|
+
readonly roomId: number;
|
|
95
|
+
readonly direction: MapData.direction;
|
|
96
|
+
readonly x1: number;
|
|
97
|
+
readonly y1: number;
|
|
98
|
+
readonly x2: number;
|
|
99
|
+
readonly y2: number;
|
|
100
|
+
readonly stroke: string;
|
|
101
|
+
readonly strokeWidth: number;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* World-space shapes for each logical layer. Same content the backend layer
|
|
105
|
+
* nodes received, but as plain SceneIR data — consumed by exporters that drive
|
|
106
|
+
* {@link buildDrawCommands} → engine renderers without going through a
|
|
107
|
+
* {@link DrawingBackend}.
|
|
108
|
+
*
|
|
109
|
+
* Order within each list mirrors the order in which the corresponding layer
|
|
110
|
+
* node received its `addNode` calls: e.g. `link` is labels → link exits → for
|
|
111
|
+
* each room (special exits, stubs); `room` is rooms → area name → area-exit
|
|
112
|
+
* labels.
|
|
113
|
+
*/
|
|
114
|
+
export type SceneShapesByLayer = {
|
|
115
|
+
grid: Shape[];
|
|
116
|
+
link: Shape[];
|
|
117
|
+
room: Shape[];
|
|
118
|
+
topLabel: Shape[];
|
|
119
|
+
};
|
|
120
|
+
/** User-defined label shape paired with its world-space bounds (for culling). */
|
|
121
|
+
export type LabelShapeRef = {
|
|
122
|
+
shape: GroupShape;
|
|
123
|
+
bounds: Bounds;
|
|
124
|
+
};
|
|
125
|
+
/** Custom-line (special-exit) shape paired with its world-space bounds (for culling). */
|
|
126
|
+
export type SpecialExitShapeRef = {
|
|
127
|
+
shape: GroupShape;
|
|
128
|
+
bounds: Bounds;
|
|
129
|
+
};
|
|
130
|
+
/** Stub shape paired with its world-space bounds (for culling). */
|
|
131
|
+
export type StubShapeRef = {
|
|
132
|
+
shape: GroupShape;
|
|
133
|
+
bounds: Bounds;
|
|
134
|
+
};
|
|
135
|
+
/** Area-exit label shape paired with its world-space bounds (for culling). */
|
|
136
|
+
export type AreaExitLabelShapeRef = {
|
|
137
|
+
shape: GroupShape;
|
|
138
|
+
bounds: Bounds;
|
|
139
|
+
};
|
|
140
|
+
export type SceneBuildResult = {
|
|
141
|
+
/** Room body shapes keyed by roomId — for cull-entry construction. */
|
|
142
|
+
roomShapeRefs: Map<number, RoomShapeRef>;
|
|
143
|
+
/** Link-exit shapes paired with bounds and area-target metadata. */
|
|
144
|
+
standaloneExitShapeRefs: StandaloneExitShapeRef[];
|
|
145
|
+
/** Non-noScaling label shapes paired with world-space bounds (for culling). */
|
|
146
|
+
labelShapeRefs: LabelShapeRef[];
|
|
147
|
+
/** Custom-line special-exit shapes paired with world-space bounds (for culling). */
|
|
148
|
+
specialExitShapeRefs: SpecialExitShapeRef[];
|
|
149
|
+
/** Stub shapes paired with world-space bounds (for culling). */
|
|
150
|
+
stubShapeRefs: StubShapeRef[];
|
|
151
|
+
/** Area-exit label shapes paired with world-space bounds (for culling). */
|
|
152
|
+
areaExitLabelShapeRefs: AreaExitLabelShapeRef[];
|
|
153
|
+
areaExitHitZones: AreaExitHitZone[];
|
|
154
|
+
drawnExits: DrawnExitEntry[];
|
|
155
|
+
drawnSpecialExits: DrawnSpecialExitEntry[];
|
|
156
|
+
drawnStubs: DrawnStubEntry[];
|
|
157
|
+
/** World-space shapes carrying {@link HitInfo} annotations — fed to {@link HitTester}. */
|
|
158
|
+
hitShapes: Shape[];
|
|
159
|
+
/**
|
|
160
|
+
* Engine-agnostic shape lists per logical layer. Drives
|
|
161
|
+
* {@link buildDrawCommands} + a per-engine renderer.
|
|
162
|
+
*/
|
|
163
|
+
sceneShapes: SceneShapesByLayer;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Engine-neutral scene composition pipeline.
|
|
167
|
+
*
|
|
168
|
+
* Walks a {@link MapData} area/plane and emits world-space {@link Shape}s per
|
|
169
|
+
* logical layer (grid / link / room / topLabel) plus the metadata downstream
|
|
170
|
+
* consumers need (cull entries, hit zones, drawn-geometry snapshots).
|
|
171
|
+
*
|
|
172
|
+
* The pipeline knows nothing about Konva, SVG, Canvas, or the
|
|
173
|
+
* {@link DrawCommandBuilder}: callers run the shape lists through whatever
|
|
174
|
+
* renderer fits their target. Both the interactive
|
|
175
|
+
* {@link KonvaRenderBackend} and the exporters consume the same
|
|
176
|
+
* {@link SceneBuildResult} this pipeline produces.
|
|
177
|
+
*/
|
|
178
|
+
export declare class ScenePipeline {
|
|
179
|
+
private readonly mapReader;
|
|
180
|
+
private readonly settings;
|
|
181
|
+
readonly exitRenderer: ExitRenderer;
|
|
182
|
+
private linkShapes;
|
|
183
|
+
private roomShapes;
|
|
184
|
+
private topLabelShapes;
|
|
185
|
+
private labelShapeRefs;
|
|
186
|
+
private specialExitShapeRefs;
|
|
187
|
+
private stubShapeRefs;
|
|
188
|
+
private areaExitLabelShapeRefs;
|
|
189
|
+
constructor(mapReader: IMapReader, settings: Settings);
|
|
190
|
+
/**
|
|
191
|
+
* Build the full scene for an area/plane.
|
|
192
|
+
* Clears layers, renders grid → labels → exits → rooms → area name.
|
|
193
|
+
* Returns data for culling and interaction (room nodes, exit data, hit zones).
|
|
194
|
+
*
|
|
195
|
+
* The `lens` filters which rooms paint and how partially-visible exits are
|
|
196
|
+
* treated. Pass {@link ALL_VISIBLE} (or omit) for an unfiltered build.
|
|
197
|
+
*/
|
|
198
|
+
buildScene(area: IArea, plane: IPlane, zIndex: number, lens?: RoomLens): SceneBuildResult;
|
|
199
|
+
getEffectiveBounds(area: IArea, plane: IPlane): {
|
|
200
|
+
minX: number;
|
|
201
|
+
maxX: number;
|
|
202
|
+
minY: number;
|
|
203
|
+
maxY: number;
|
|
204
|
+
};
|
|
205
|
+
private renderRooms;
|
|
206
|
+
private renderLinkExits;
|
|
207
|
+
/**
|
|
208
|
+
* Build a stub anchored at the visible endpoint of an exit, pointing
|
|
209
|
+
* toward the hidden one. Returns undefined when the exit can't be drawn
|
|
210
|
+
* as a stub (no planar direction on the visible side, both sides hidden,
|
|
211
|
+
* or both sides visible — the last is a caller bug).
|
|
212
|
+
*/
|
|
213
|
+
private buildLensStub;
|
|
214
|
+
private emitLensStub;
|
|
215
|
+
private getRoomEdgePoint;
|
|
216
|
+
/**
|
|
217
|
+
* Build the world-space shape tree for one inter-room exit. Used by the
|
|
218
|
+
* live renderer's current-room overlay path to recolour a single exit
|
|
219
|
+
* without rebuilding the whole scene.
|
|
220
|
+
*/
|
|
221
|
+
buildExitShape(data: ExitDrawData): GroupShape;
|
|
222
|
+
private renderLabels;
|
|
223
|
+
private renderAreaExitLabels;
|
|
224
|
+
private renderAreaName;
|
|
225
|
+
}
|
|
226
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type SvgOverlays = {
|
|
2
|
+
position?: {
|
|
3
|
+
roomId: number;
|
|
4
|
+
};
|
|
5
|
+
highlights?: Array<{
|
|
6
|
+
roomId: number;
|
|
7
|
+
color: string;
|
|
8
|
+
}>;
|
|
9
|
+
paths?: Array<{
|
|
10
|
+
locations: number[];
|
|
11
|
+
color: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
export type SvgExportOptions = {
|
|
15
|
+
/** Room ID to center the export on. If omitted, exports the full area. */
|
|
16
|
+
roomId?: number;
|
|
17
|
+
/** Padding in map units around the exported region. Default: 3 */
|
|
18
|
+
padding?: number;
|
|
19
|
+
/** Overlay data (position marker, highlights, paths) to include in the export. */
|
|
20
|
+
overlays?: SvgOverlays;
|
|
21
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight typed event emitter.
|
|
3
|
+
* Also dispatches DOM CustomEvents on an optional container element
|
|
4
|
+
* for backwards compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export declare class TypedEventEmitter<EventMap extends Record<string, unknown>> {
|
|
7
|
+
private listeners;
|
|
8
|
+
private container?;
|
|
9
|
+
/**
|
|
10
|
+
* @param container Optional DOM element to also dispatch CustomEvents on (for backwards compat)
|
|
11
|
+
*/
|
|
12
|
+
constructor(container?: HTMLElement);
|
|
13
|
+
on<K extends keyof EventMap>(event: K, handler: (detail: EventMap[K]) => void): void;
|
|
14
|
+
off<K extends keyof EventMap>(event: K, handler: (detail: EventMap[K]) => void): void;
|
|
15
|
+
removeAllListeners(): void;
|
|
16
|
+
emit<K extends keyof EventMap>(event: K, detail: EventMap[K]): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { MudletMap, readMapFromBuffer } from 'mudlet-map-binary-reader';
|
|
2
|
+
import { IMapReader } from '../reader/MapReader';
|
|
3
|
+
import { IArea } from '../reader/Area';
|
|
4
|
+
/**
|
|
5
|
+
* {@link IMapReader} implementation backed by a parsed Mudlet binary map.
|
|
6
|
+
*
|
|
7
|
+
* Convenience wrapper around the existing {@link MapReader} that converts a
|
|
8
|
+
* {@link MudletMap} (the in-memory binary model from
|
|
9
|
+
* `mudlet-map-binary-reader`) into the renderer's `{mapData, colors}` shape
|
|
10
|
+
* via `readerExport()`, then forwards every `IMapReader` call to the wrapped
|
|
11
|
+
* reader.
|
|
12
|
+
*
|
|
13
|
+
* Useful for downstream apps (the upstream Mudix client is one) that already
|
|
14
|
+
* own binary `.dat` bytes and want a single object they can hand to
|
|
15
|
+
* {@link MapRenderer} without staging a separate JSON export step.
|
|
16
|
+
*
|
|
17
|
+
* `mudlet-map-binary-reader` is a `peerDependency`; consumers who do not use
|
|
18
|
+
* binary maps never pay the bundle cost.
|
|
19
|
+
*/
|
|
20
|
+
export default class BinaryMapReader implements IMapReader {
|
|
21
|
+
private readonly reader;
|
|
22
|
+
/** Build directly from a parsed {@link MudletMap}. */
|
|
23
|
+
constructor(model: MudletMap);
|
|
24
|
+
/**
|
|
25
|
+
* Parse the given binary map buffer and construct a reader from it.
|
|
26
|
+
* In Node, pass `fs.readFileSync(path)`; in the browser, construct a
|
|
27
|
+
* `Buffer` from an `ArrayBuffer` (e.g. via the `buffer` polyfill).
|
|
28
|
+
*/
|
|
29
|
+
static fromBuffer(buf: Parameters<typeof readMapFromBuffer>[0]): BinaryMapReader;
|
|
30
|
+
getArea(areaId: number): IArea;
|
|
31
|
+
getAreas(): IArea[];
|
|
32
|
+
getRooms(): MapData.Room[];
|
|
33
|
+
getRoom(roomId: number): MapData.Room;
|
|
34
|
+
getColorValue(envId: number): string;
|
|
35
|
+
getSymbolColor(envId: number, opacity?: number): string;
|
|
36
|
+
}
|
package/dist/binary.mjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { t as e } from "./MapReader-mU_4JWv_.js";
|
|
2
|
+
import { readMapFromBuffer as t, readerExport as n } from "mudlet-map-binary-reader";
|
|
3
|
+
//#region src/binary/BinaryMapReader.ts
|
|
4
|
+
var r = class r {
|
|
5
|
+
constructor(t) {
|
|
6
|
+
let { mapData: r, colors: i } = n(t);
|
|
7
|
+
this.reader = new e(r, i);
|
|
8
|
+
}
|
|
9
|
+
static fromBuffer(e) {
|
|
10
|
+
return new r(t(e));
|
|
11
|
+
}
|
|
12
|
+
getArea(e) {
|
|
13
|
+
return this.reader.getArea(e);
|
|
14
|
+
}
|
|
15
|
+
getAreas() {
|
|
16
|
+
return this.reader.getAreas();
|
|
17
|
+
}
|
|
18
|
+
getRooms() {
|
|
19
|
+
return this.reader.getRooms();
|
|
20
|
+
}
|
|
21
|
+
getRoom(e) {
|
|
22
|
+
return this.reader.getRoom(e);
|
|
23
|
+
}
|
|
24
|
+
getColorValue(e) {
|
|
25
|
+
return this.reader.getColorValue(e);
|
|
26
|
+
}
|
|
27
|
+
getSymbolColor(e, t) {
|
|
28
|
+
return this.reader.getSymbolColor(e, t);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { r as BinaryMapReader };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=binary.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary.mjs","names":[],"sources":["../src/binary/BinaryMapReader.ts"],"sourcesContent":["import {\n type MudletMap,\n readerExport,\n readMapFromBuffer,\n} from \"mudlet-map-binary-reader\";\nimport MapReader, {type IMapReader} from \"../reader/MapReader\";\nimport type {IArea} from \"../reader/Area\";\n\n/**\n * {@link IMapReader} implementation backed by a parsed Mudlet binary map.\n *\n * Convenience wrapper around the existing {@link MapReader} that converts a\n * {@link MudletMap} (the in-memory binary model from\n * `mudlet-map-binary-reader`) into the renderer's `{mapData, colors}` shape\n * via `readerExport()`, then forwards every `IMapReader` call to the wrapped\n * reader.\n *\n * Useful for downstream apps (the upstream Mudix client is one) that already\n * own binary `.dat` bytes and want a single object they can hand to\n * {@link MapRenderer} without staging a separate JSON export step.\n *\n * `mudlet-map-binary-reader` is a `peerDependency`; consumers who do not use\n * binary maps never pay the bundle cost.\n */\nexport default class BinaryMapReader implements IMapReader {\n private readonly reader: MapReader;\n\n /** Build directly from a parsed {@link MudletMap}. */\n constructor(model: MudletMap) {\n const {mapData, colors} = readerExport(model);\n // RendererRoom (binary-reader output) and MapData.Room (renderer\n // input) overlap structurally — RendererRoom is missing only\n // `areaId`, which the renderer never reads from rooms (only from\n // the area). Cast through `unknown` to bridge the nominal gap.\n this.reader = new MapReader(mapData as unknown as MapData.Map, colors);\n }\n\n /**\n * Parse the given binary map buffer and construct a reader from it.\n * In Node, pass `fs.readFileSync(path)`; in the browser, construct a\n * `Buffer` from an `ArrayBuffer` (e.g. via the `buffer` polyfill).\n */\n static fromBuffer(buf: Parameters<typeof readMapFromBuffer>[0]): BinaryMapReader {\n return new BinaryMapReader(readMapFromBuffer(buf));\n }\n\n // --- IMapReader forwarding ---\n\n getArea(areaId: number): IArea {\n return this.reader.getArea(areaId);\n }\n\n getAreas(): IArea[] {\n return this.reader.getAreas();\n }\n\n getRooms(): MapData.Room[] {\n return this.reader.getRooms();\n }\n\n getRoom(roomId: number): MapData.Room {\n return this.reader.getRoom(roomId);\n }\n\n getColorValue(envId: number): string {\n return this.reader.getColorValue(envId);\n }\n\n getSymbolColor(envId: number, opacity?: number): string {\n return this.reader.getSymbolColor(envId, opacity);\n }\n}\n"],"mappings":";;;AAwBA,IAAqB,IAArB,MAAqB,EAAsC;CAIvD,YAAY,GAAkB;EAC1B,IAAM,EAAC,YAAS,cAAU,EAAa,EAAM;AAK7C,OAAK,SAAS,IAAI,EAAU,GAAmC,EAAO;;CAQ1E,OAAO,WAAW,GAA+D;AAC7E,SAAO,IAAI,EAAgB,EAAkB,EAAI,CAAC;;CAKtD,QAAQ,GAAuB;AAC3B,SAAO,KAAK,OAAO,QAAQ,EAAO;;CAGtC,WAAoB;AAChB,SAAO,KAAK,OAAO,UAAU;;CAGjC,WAA2B;AACvB,SAAO,KAAK,OAAO,UAAU;;CAGjC,QAAQ,GAA8B;AAClC,SAAO,KAAK,OAAO,QAAQ,EAAO;;CAGtC,cAAc,GAAuB;AACjC,SAAO,KAAK,OAAO,cAAc,EAAM;;CAG3C,eAAe,GAAe,GAA0B;AACpD,SAAO,KAAK,OAAO,eAAe,GAAO,EAAQ"}
|
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
private batchDepth;
|
|
35
|
+
private batchDirty;
|
|
36
|
+
constructor(width: number, height: number);
|
|
37
|
+
getScale(): number;
|
|
38
|
+
setZoom(zoom: number): boolean;
|
|
39
|
+
/** Zoom keeping the center of the viewport fixed. */
|
|
40
|
+
zoomToCenter(zoom: number): boolean;
|
|
41
|
+
/** Zoom keeping a specific screen point fixed (for mouse wheel zoom). */
|
|
42
|
+
zoomToPoint(zoom: number, screenX: number, screenY: number): boolean;
|
|
43
|
+
/** Bounds of the visible area in map space. */
|
|
44
|
+
getViewportBounds(): ViewportBounds;
|
|
45
|
+
/**
|
|
46
|
+
* Map-space bounds to use for culling. When `cullingBounds` is a
|
|
47
|
+
* screen-pixel sub-rect it is converted to map space via the current
|
|
48
|
+
* camera transform; otherwise the full viewport is returned.
|
|
49
|
+
*/
|
|
50
|
+
getCullingViewport(cullingBounds?: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
} | null): ViewportBounds;
|
|
56
|
+
/**
|
|
57
|
+
* Create a Camera whose full viewport covers exactly the given world-space bounds.
|
|
58
|
+
* Used by headless exporters that need a Camera but have no real display.
|
|
59
|
+
*/
|
|
60
|
+
static forMapBounds(minX: number, maxX: number, minY: number, maxY: number): Camera;
|
|
61
|
+
/**
|
|
62
|
+
* Create a Camera from an explicit render-camera transform (scale + offset).
|
|
63
|
+
* Used by {@link CanvasExporter} to derive culling bounds from the already-
|
|
64
|
+
* computed fitted transform without re-doing the letterbox math.
|
|
65
|
+
*/
|
|
66
|
+
static forRenderCamera(width: number, height: number, scale: number, offsetX: number, offsetY: number): Camera;
|
|
67
|
+
/** Convert client/screen coordinates to map coordinates. */
|
|
68
|
+
clientToMapPoint(clientX: number, clientY: number, containerOffset?: {
|
|
69
|
+
left: number;
|
|
70
|
+
top: number;
|
|
71
|
+
}): {
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
} | null;
|
|
75
|
+
/** Center on a map coordinate, instantly. */
|
|
76
|
+
panToMapPoint(x: number, y: number): void;
|
|
77
|
+
/** Center on a map coordinate, with optional animation. */
|
|
78
|
+
panToMapPointAnimated(x: number, y: number, instant: boolean): void;
|
|
79
|
+
/**
|
|
80
|
+
* Compute the zoom level that would fit the given map bounds in the current
|
|
81
|
+
* viewport (with the same padding/insets as {@link fitToMapBounds}).
|
|
82
|
+
*/
|
|
83
|
+
computeFitZoom(minX: number, maxX: number, minY: number, maxY: number, insets?: {
|
|
84
|
+
top?: number;
|
|
85
|
+
right?: number;
|
|
86
|
+
bottom?: number;
|
|
87
|
+
left?: number;
|
|
88
|
+
}): number;
|
|
89
|
+
/**
|
|
90
|
+
* Fit the camera to show the given map bounds with padding.
|
|
91
|
+
* Optional `insets` (screen pixels) reserve space at each edge.
|
|
92
|
+
*/
|
|
93
|
+
fitToMapBounds(minX: number, maxX: number, minY: number, maxY: number, insets?: {
|
|
94
|
+
top?: number;
|
|
95
|
+
right?: number;
|
|
96
|
+
bottom?: number;
|
|
97
|
+
left?: number;
|
|
98
|
+
}): void;
|
|
99
|
+
setSize(width: number, height: number): void;
|
|
100
|
+
startDrag(screenX: number, screenY: number): void;
|
|
101
|
+
updateDrag(screenX: number, screenY: number): void;
|
|
102
|
+
endDrag(): void;
|
|
103
|
+
isDragging(): boolean;
|
|
104
|
+
private animate;
|
|
105
|
+
cancelAnimation(): void;
|
|
106
|
+
isAnimating(): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Run a function that performs multiple camera mutations and emit only one
|
|
109
|
+
* `change` event at the end (if anything actually mutated). Use this when a
|
|
110
|
+
* single logical operation needs to touch more than one camera field —
|
|
111
|
+
* resize-then-recenter, for example — so subscribers never observe a
|
|
112
|
+
* transient inconsistent state (new size with stale position).
|
|
113
|
+
*
|
|
114
|
+
* Nested batches are supported: only the outermost batch emits.
|
|
115
|
+
*/
|
|
116
|
+
batch<T>(fn: () => T): T;
|
|
117
|
+
private notify;
|
|
118
|
+
}
|
|
@@ -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,25 @@
|
|
|
1
|
+
export type PlanarDirection = "north" | "south" | "east" | "west" | "northeast" | "northwest" | "southeast" | "southwest";
|
|
2
|
+
export declare const planarDirections: PlanarDirection[];
|
|
3
|
+
export declare const oppositeDirections: Record<PlanarDirection, PlanarDirection>;
|
|
4
|
+
export declare function movePoint(x: number, y: number, direction?: MapData.direction, distance?: number): {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Calculate the edge point of a rounded rectangle for a given direction.
|
|
10
|
+
* Cardinal directions use the flat edge (same as rectangle).
|
|
11
|
+
* Diagonal directions intersect the corner arc.
|
|
12
|
+
*/
|
|
13
|
+
export declare function movePointRoundedRect(x: number, y: number, direction?: MapData.direction, distance?: number, cornerRadius?: number): {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Calculate the edge point of a circle for a given direction
|
|
19
|
+
* For circles, we need to calculate the exact point on the circle's circumference
|
|
20
|
+
* based on the angle to the direction
|
|
21
|
+
*/
|
|
22
|
+
export declare function movePointCircle(x: number, y: number, direction?: MapData.direction, radius?: number): {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
};
|
|
@@ -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[];
|