mudlet-map-renderer 2.0.0 → 2.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 +14 -0
- package/dist/{MapReader-mU_4JWv_.js → MapReader-Brzg-X7T.js} +1 -1
- package/dist/{MapReader-mU_4JWv_.js.map → MapReader-Brzg-X7T.js.map} +1 -1
- package/dist/MapState.d.ts +6 -1
- package/dist/SvgTypes.d.ts +1 -1
- package/dist/assets/worker-DtQws85m.js.map +1 -0
- package/dist/binary.mjs +1 -1
- package/dist/export/CanvasExporter.d.ts +1 -1
- package/dist/export/flushSceneShapes.d.ts +1 -1
- package/dist/flushSceneShapes-Duhi0OQv.js +2937 -0
- package/dist/flushSceneShapes-Duhi0OQv.js.map +1 -0
- package/dist/hit/HitTester.d.ts +19 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +880 -3380
- package/dist/index.mjs.map +1 -1
- package/dist/offscreen.mjs +355 -0
- package/dist/offscreen.mjs.map +1 -0
- package/dist/overlay/SceneOverlay.d.ts +16 -3
- package/dist/rendering/KonvaRenderBackend.d.ts +5 -1
- package/dist/rendering/MapRenderer.d.ts +18 -4
- package/dist/rendering/offscreen/OffscreenCanvasBackend.d.ts +109 -0
- package/dist/rendering/offscreen/index.d.ts +11 -0
- package/dist/rendering/offscreen/protocol.d.ts +100 -0
- package/dist/rendering/offscreen/renderFrame.d.ts +28 -0
- package/dist/rendering/offscreen/serializeTransform.d.ts +20 -0
- package/dist/rendering/offscreen/worker.d.ts +15 -0
- package/dist/scene/OverlayStyle.d.ts +7 -3
- package/dist/scene/Shape.d.ts +7 -0
- package/dist/scene/elements/OverlayLayout.d.ts +3 -0
- package/dist/style/Style.d.ts +12 -0
- package/dist/style/index.d.ts +10 -1
- package/dist/style/shape/GraphPaperStyle.d.ts +16 -0
- package/dist/style/shape/StainedGlassStyle.d.ts +15 -0
- package/dist/style/shape/TopographicStyle.d.ts +14 -0
- package/dist/style/shape/WatercolorStyle.d.ts +32 -0
- package/dist/style/shape/index.d.ts +5 -0
- package/dist/style/shape/paintMap.d.ts +8 -0
- package/dist/types/Settings.d.ts +11 -3
- package/package.json +6 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { InteractiveBackend } from '../MapRenderer';
|
|
2
|
+
import { MapState } from '../../MapState';
|
|
3
|
+
import { RendererEventMap } from '../../types/Settings';
|
|
4
|
+
import { Camera } from '../../camera/Camera';
|
|
5
|
+
import { CullingManager } from '../../CullingManager';
|
|
6
|
+
import { HitTester } from '../../hit/HitTester';
|
|
7
|
+
import { TypedEventEmitter } from '../../TypedEventEmitter';
|
|
8
|
+
import { DrawnExitEntry, DrawnSpecialExitEntry, DrawnStubEntry } from '../../ScenePipeline';
|
|
9
|
+
import { Style } from '../../style/Style';
|
|
10
|
+
import { CoordFn } from '../../coord/CoordFn';
|
|
11
|
+
import { SceneOverlay } from '../../overlay/SceneOverlay';
|
|
12
|
+
import { LiveEffect } from '../../overlay/LiveEffect';
|
|
13
|
+
import { ExportCanvas } from '../../export/Exporter';
|
|
14
|
+
import { MainToWorkerMessage, WorkerToMainMessage } from './protocol';
|
|
15
|
+
/** Transport the backend talks to. A real `Worker` satisfies this directly. */
|
|
16
|
+
export interface WorkerTransport {
|
|
17
|
+
postMessage(message: MainToWorkerMessage, transfer?: Transferable[]): void;
|
|
18
|
+
addEventListener?(type: "message", handler: (ev: {
|
|
19
|
+
data: WorkerToMainMessage;
|
|
20
|
+
}) => void): void;
|
|
21
|
+
onmessage?: ((ev: {
|
|
22
|
+
data: WorkerToMainMessage;
|
|
23
|
+
}) => void) | null;
|
|
24
|
+
terminate?(): void;
|
|
25
|
+
}
|
|
26
|
+
export interface OffscreenBackendOptions {
|
|
27
|
+
/** Pre-created transport (used by the inline-worker factory and by tests). */
|
|
28
|
+
transport?: WorkerTransport;
|
|
29
|
+
/** Lazily create the transport. Ignored when {@link transport} is provided. */
|
|
30
|
+
createTransport?: () => WorkerTransport;
|
|
31
|
+
/** Override the device pixel ratio (tests / forcing 1x). */
|
|
32
|
+
devicePixelRatio?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare class OffscreenCanvasBackend implements InteractiveBackend {
|
|
35
|
+
readonly camera: Camera;
|
|
36
|
+
readonly culling: CullingManager;
|
|
37
|
+
readonly events: TypedEventEmitter<RendererEventMap>;
|
|
38
|
+
readonly hitTester: HitTester;
|
|
39
|
+
private readonly state;
|
|
40
|
+
private readonly container?;
|
|
41
|
+
private readonly transport?;
|
|
42
|
+
private readonly pipeline;
|
|
43
|
+
private readonly dpr;
|
|
44
|
+
private currentStyle;
|
|
45
|
+
private _coordinateTransform;
|
|
46
|
+
private coordinateInverse;
|
|
47
|
+
private coordinateLayerOffset;
|
|
48
|
+
private lastResult?;
|
|
49
|
+
private lastHitShapes;
|
|
50
|
+
private boundsByShape;
|
|
51
|
+
private interactionHandler?;
|
|
52
|
+
private cameraChangeHandler?;
|
|
53
|
+
private readonly sceneOverlays;
|
|
54
|
+
private readonly viewportSubscribers;
|
|
55
|
+
private readonly liveEffects;
|
|
56
|
+
private liveEffectStage?;
|
|
57
|
+
private liveEffectLayer?;
|
|
58
|
+
private liveEffectHost?;
|
|
59
|
+
private readonly pendingExports;
|
|
60
|
+
private exportSeq;
|
|
61
|
+
private destroyed;
|
|
62
|
+
constructor(state: MapState, container?: HTMLDivElement, options?: OffscreenBackendOptions);
|
|
63
|
+
get coordinateTransform(): CoordFn;
|
|
64
|
+
private post;
|
|
65
|
+
private postSettings;
|
|
66
|
+
private postCamera;
|
|
67
|
+
private postScene;
|
|
68
|
+
private postOverlays;
|
|
69
|
+
private styleContext;
|
|
70
|
+
private styleOne;
|
|
71
|
+
private styleShapes;
|
|
72
|
+
/** Style a scene layer, carrying each shape's world-space cull bounds through. */
|
|
73
|
+
private styleLayer;
|
|
74
|
+
refresh(): void;
|
|
75
|
+
private buildBoundsMap;
|
|
76
|
+
/** Port of {@link KonvaRenderBackend.updateCurrentRoomOverlay} returning shapes. */
|
|
77
|
+
private buildCurrentRoomOverlayShapes;
|
|
78
|
+
setStyle(style: Style): void;
|
|
79
|
+
private applyStyleTransforms;
|
|
80
|
+
private onCameraChange;
|
|
81
|
+
private subscribeToState;
|
|
82
|
+
private onPositionChanged;
|
|
83
|
+
updateBackground(): void;
|
|
84
|
+
addSceneOverlay(id: string, overlay: SceneOverlay): void;
|
|
85
|
+
removeSceneOverlay(id: string): void;
|
|
86
|
+
getSceneOverlays(): Iterable<SceneOverlay>;
|
|
87
|
+
private createOverlayContext;
|
|
88
|
+
private ensureEffectStage;
|
|
89
|
+
/** Mirror the camera transform onto the effect stage so effects align with the map. */
|
|
90
|
+
private syncEffectStage;
|
|
91
|
+
addLiveEffect(id: string, effect: LiveEffect): void;
|
|
92
|
+
removeLiveEffect(id: string): void;
|
|
93
|
+
getDrawnExits(): readonly DrawnExitEntry[];
|
|
94
|
+
getDrawnSpecialExits(): readonly DrawnSpecialExitEntry[];
|
|
95
|
+
getDrawnStubs(): readonly DrawnStubEntry[];
|
|
96
|
+
/**
|
|
97
|
+
* Not supported with the worker backend — the live canvas is owned by the
|
|
98
|
+
* worker and cannot be read synchronously here. Use the headless
|
|
99
|
+
* `CanvasExporter` / `PngBytesExporter` (they rebuild from state), or the
|
|
100
|
+
* async {@link captureViewport} for a live snapshot.
|
|
101
|
+
*/
|
|
102
|
+
exportCanvas(): ExportCanvas | undefined;
|
|
103
|
+
/** Async live-viewport snapshot via a worker round-trip. */
|
|
104
|
+
captureViewport(options?: {
|
|
105
|
+
pixelRatio?: number;
|
|
106
|
+
}): Promise<ImageBitmap>;
|
|
107
|
+
private handleWorkerMessage;
|
|
108
|
+
destroy(): void;
|
|
109
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MapState } from '../../MapState';
|
|
2
|
+
import { InteractiveBackend } from '../MapRenderer';
|
|
3
|
+
import { OffscreenBackendOptions } from './OffscreenCanvasBackend';
|
|
4
|
+
export { OffscreenCanvasBackend } from './OffscreenCanvasBackend';
|
|
5
|
+
export type { OffscreenBackendOptions, WorkerTransport } from './OffscreenCanvasBackend';
|
|
6
|
+
export type { MainToWorkerMessage, WorkerToMainMessage, SerializableTransform } from './protocol';
|
|
7
|
+
/**
|
|
8
|
+
* Build a backend factory for {@link MapRenderer}'s `backendFactory` parameter.
|
|
9
|
+
* Pass the same `container` you give `MapRenderer`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createOffscreenBackend(container?: HTMLDivElement, options?: OffscreenBackendOptions): (state: MapState) => InteractiveBackend;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Shape } from '../../scene/Shape';
|
|
2
|
+
import { Settings, ViewportBounds } from '../../types/Settings';
|
|
3
|
+
/** World-space axis-aligned bounds used for culling. */
|
|
4
|
+
export interface Bounds {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Flattened coordinate transform. `Style.worldToScene` / `sceneToWorld` are
|
|
12
|
+
* closures and cannot cross `postMessage`; we sample them into affine matrices
|
|
13
|
+
* on the main thread. `'identity'` is the fast path for every flat style.
|
|
14
|
+
*
|
|
15
|
+
* Affine matrices follow the DOM/Canvas convention `[a, b, c, d, e, f]`:
|
|
16
|
+
* `x' = a·x + c·y + e`, `y' = b·x + d·y + f`.
|
|
17
|
+
*/
|
|
18
|
+
export type SerializableTransform = {
|
|
19
|
+
kind: "identity";
|
|
20
|
+
} | {
|
|
21
|
+
kind: "affine";
|
|
22
|
+
/** World → scene (for culling-bounds projection). */
|
|
23
|
+
forward: AffineMatrix;
|
|
24
|
+
/** Scene → world (for grid Cartesian-bounds computation). */
|
|
25
|
+
inverse: AffineMatrix;
|
|
26
|
+
};
|
|
27
|
+
export type AffineMatrix = [number, number, number, number, number, number];
|
|
28
|
+
/** Camera transform needed to project world coordinates into render space. */
|
|
29
|
+
export interface RenderCamera {
|
|
30
|
+
scale: number;
|
|
31
|
+
offsetX: number;
|
|
32
|
+
offsetY: number;
|
|
33
|
+
}
|
|
34
|
+
/** One scene layer: styled shapes plus per-shape world-space cull bounds. */
|
|
35
|
+
export interface LayerPayload {
|
|
36
|
+
/** Already-styled, scene-space shapes (identity style → world-space). */
|
|
37
|
+
shapes: Shape[];
|
|
38
|
+
/**
|
|
39
|
+
* Per-shape world-space cull bounds, index-aligned with {@link shapes}.
|
|
40
|
+
* `null` marks an unmanaged pass-through (area name, noScaling label) that
|
|
41
|
+
* is always drawn. Shapes fanned out by a style share their parent bounds.
|
|
42
|
+
*/
|
|
43
|
+
bounds: Array<Bounds | null>;
|
|
44
|
+
}
|
|
45
|
+
export interface InitMessage {
|
|
46
|
+
type: "init";
|
|
47
|
+
canvas: OffscreenCanvas;
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
/** Device pixel ratio for crisp rendering on HiDPI displays. */
|
|
51
|
+
dpr: number;
|
|
52
|
+
settings: Settings;
|
|
53
|
+
}
|
|
54
|
+
export interface SettingsMessage {
|
|
55
|
+
type: "settings";
|
|
56
|
+
settings: Settings;
|
|
57
|
+
}
|
|
58
|
+
export interface SceneMessage {
|
|
59
|
+
type: "scene";
|
|
60
|
+
link: LayerPayload;
|
|
61
|
+
room: LayerPayload;
|
|
62
|
+
topLabel: Shape[];
|
|
63
|
+
transform: SerializableTransform;
|
|
64
|
+
}
|
|
65
|
+
export interface OverlaysMessage {
|
|
66
|
+
type: "overlays";
|
|
67
|
+
/** Already-styled overlay shapes (current-room overlay + built-in overlays). */
|
|
68
|
+
shapes: Shape[];
|
|
69
|
+
}
|
|
70
|
+
export interface CameraMessage {
|
|
71
|
+
type: "camera";
|
|
72
|
+
camera: RenderCamera;
|
|
73
|
+
viewport: ViewportBounds;
|
|
74
|
+
width: number;
|
|
75
|
+
height: number;
|
|
76
|
+
}
|
|
77
|
+
export interface ResizeMessage {
|
|
78
|
+
type: "resize";
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
dpr: number;
|
|
82
|
+
}
|
|
83
|
+
export interface ExportMessage {
|
|
84
|
+
type: "export";
|
|
85
|
+
requestId: number;
|
|
86
|
+
pixelRatio: number;
|
|
87
|
+
}
|
|
88
|
+
export interface DestroyMessage {
|
|
89
|
+
type: "destroy";
|
|
90
|
+
}
|
|
91
|
+
export type MainToWorkerMessage = InitMessage | SettingsMessage | SceneMessage | OverlaysMessage | CameraMessage | ResizeMessage | ExportMessage | DestroyMessage;
|
|
92
|
+
export interface ReadyMessage {
|
|
93
|
+
type: "ready";
|
|
94
|
+
}
|
|
95
|
+
export interface ExportResultMessage {
|
|
96
|
+
type: "export";
|
|
97
|
+
requestId: number;
|
|
98
|
+
bitmap: ImageBitmap;
|
|
99
|
+
}
|
|
100
|
+
export type WorkerToMainMessage = ReadyMessage | ExportResultMessage;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Settings, ViewportBounds } from '../../types/Settings';
|
|
2
|
+
import { Shape } from '../../scene/Shape';
|
|
3
|
+
import { ImageFactory } from '../../render/CanvasRenderer';
|
|
4
|
+
import { LayerPayload, RenderCamera, SerializableTransform } from './protocol';
|
|
5
|
+
export interface FrameScene {
|
|
6
|
+
link: LayerPayload;
|
|
7
|
+
room: LayerPayload;
|
|
8
|
+
topLabel: Shape[];
|
|
9
|
+
transform: SerializableTransform;
|
|
10
|
+
}
|
|
11
|
+
export interface FrameInput {
|
|
12
|
+
scene: FrameScene | null;
|
|
13
|
+
overlays: Shape[];
|
|
14
|
+
camera: RenderCamera;
|
|
15
|
+
viewport: ViewportBounds;
|
|
16
|
+
settings: Settings;
|
|
17
|
+
/** Logical (CSS) pixel dimensions; HiDPI scaling is applied by the caller. */
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
/**
|
|
21
|
+
* Resolves an image shape's `src` to a drawable source. In the worker this
|
|
22
|
+
* returns a cached {@link ImageBitmap} (or `null` while it decodes), so
|
|
23
|
+
* data-URL labels and the ambient-light vignette render off-thread.
|
|
24
|
+
*/
|
|
25
|
+
imageFactory?: ImageFactory;
|
|
26
|
+
}
|
|
27
|
+
/** Render one frame of the scene + overlays onto `ctx`. */
|
|
28
|
+
export declare function renderFrame(ctx: CanvasRenderingContext2D, input: FrameInput): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Style } from '../../style/Style';
|
|
2
|
+
import { SerializableTransform } from './protocol';
|
|
3
|
+
type TransformFn = (x: number, y: number) => {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
};
|
|
7
|
+
/** Build the flattened transform for a style. Identity styles short-circuit. */
|
|
8
|
+
export declare function serializeTransform(style: Style): SerializableTransform;
|
|
9
|
+
/**
|
|
10
|
+
* World → scene projector for the worker's cull-bounds test. Returns
|
|
11
|
+
* `undefined` for the identity transform so callers can skip projection.
|
|
12
|
+
*/
|
|
13
|
+
export declare function forwardFn(transform: SerializableTransform): TransformFn | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Scene → world projector for the worker's grid Cartesian-bounds computation.
|
|
16
|
+
* Returns `undefined` for the identity transform (grid layout treats absent
|
|
17
|
+
* inverse as identity).
|
|
18
|
+
*/
|
|
19
|
+
export declare function inverseFn(transform: SerializableTransform): TransformFn | undefined;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OffscreenCanvas worker entry.
|
|
3
|
+
*
|
|
4
|
+
* Thin dispatcher around {@link renderFrame}: owns the transferred
|
|
5
|
+
* `OffscreenCanvas`, stores the latest scene / overlays / camera / settings,
|
|
6
|
+
* and coalesces redraws onto one animation frame (only the latest camera
|
|
7
|
+
* matters, so queued messages are harmless). Resizing a transferred canvas can
|
|
8
|
+
* only happen here, so size/DPR changes are applied worker-side.
|
|
9
|
+
*
|
|
10
|
+
* This module is bundled standalone (see vite.config.ts). It must import ONLY
|
|
11
|
+
* worker-safe code — never Konva, `textMeasure`, or anything touching
|
|
12
|
+
* `document`. A stray such import would surface as a runtime error in the
|
|
13
|
+
* worker and a Konva chunk in the build.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
@@ -7,15 +7,19 @@ export type HighlightData = {
|
|
|
7
7
|
/** For circle: radius. For rect: half-size. */
|
|
8
8
|
size: number;
|
|
9
9
|
cornerRadius: number;
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* One or more colours. A single colour draws the classic ring/marker; two
|
|
12
|
+
* or more split the highlight into that many equal pie wedges (one colour
|
|
13
|
+
* each).
|
|
14
|
+
*/
|
|
15
|
+
colors: string[];
|
|
11
16
|
strokeAlpha: number;
|
|
12
17
|
strokeWidth: number;
|
|
13
|
-
fillColor: string;
|
|
14
18
|
fillAlpha: number;
|
|
15
19
|
dash?: number[];
|
|
16
20
|
dashEnabled: boolean;
|
|
17
21
|
};
|
|
18
|
-
export declare function computeHighlight(room: MapData.Room, color: string, settings: Settings): HighlightData;
|
|
22
|
+
export declare function computeHighlight(room: MapData.Room, color: string | string[], settings: Settings): HighlightData;
|
|
19
23
|
export type PositionMarkerData = {
|
|
20
24
|
shape: 'circle' | 'rect';
|
|
21
25
|
cx: number;
|
package/dist/scene/Shape.d.ts
CHANGED
|
@@ -62,6 +62,13 @@ export interface Paint {
|
|
|
62
62
|
}
|
|
63
63
|
/** True when `fill` is a gradient object rather than a colour string. */
|
|
64
64
|
export declare function isGradientFill(fill: FillStyle | undefined): fill is LinearGradient | RadialGradient;
|
|
65
|
+
/**
|
|
66
|
+
* Resolve a paint's effective dash pattern. Returns the dash only when it is
|
|
67
|
+
* present AND not explicitly disabled (`dashEnabled === false` blanks it).
|
|
68
|
+
* Renderers call this so every shape kind — rect, circle, line — honours
|
|
69
|
+
* `dashEnabled` identically.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveDash(dash: number[] | undefined, dashEnabled: boolean | undefined): number[] | undefined;
|
|
65
72
|
/**
|
|
66
73
|
* Apply a camera-style affine (translate by world origin, scale uniformly,
|
|
67
74
|
* translate by render offset) to a fill. Strings pass through unchanged.
|
|
@@ -6,6 +6,9 @@ import { Shape } from '../Shape';
|
|
|
6
6
|
* a group) so the corner dashes line up cleanly — each side's dash pattern
|
|
7
7
|
* starts fresh at the corner instead of wrapping continuously around the
|
|
8
8
|
* perimeter (same approach as the backend renderer).
|
|
9
|
+
*
|
|
10
|
+
* When the highlight carries more than one colour the ring is split into that
|
|
11
|
+
* many equal pie wedges via {@link highlightWedgesToShape}.
|
|
9
12
|
*/
|
|
10
13
|
export declare function highlightToShape(data: HighlightData): Shape;
|
|
11
14
|
/** Build the player-position marker. */
|
package/dist/style/Style.d.ts
CHANGED
|
@@ -28,6 +28,18 @@ export interface Style {
|
|
|
28
28
|
x: number;
|
|
29
29
|
y: number;
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Optional extra scene-space offset that {@link transform} applies to a
|
|
33
|
+
* given layer's groups but {@link worldToScene} does not capture. Isometric
|
|
34
|
+
* lowers the `link` layer by the cube depth so connectors meet the cube
|
|
35
|
+
* base; without mirroring that here, {@link HitTester} would place exit hit
|
|
36
|
+
* zones a cube-height above the drawn connectors. Returns `{x:0, y:0}` for
|
|
37
|
+
* layers it does not shift.
|
|
38
|
+
*/
|
|
39
|
+
sceneLayerOffset?(layer: Shape["layer"]): {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
};
|
|
31
43
|
}
|
|
32
44
|
/** Identity style — passes shapes through unchanged. */
|
|
33
45
|
export declare const identityStyle: Style;
|
package/dist/style/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Style } from './Style';
|
|
|
2
2
|
import { SketchyOptions } from './shape/SketchyStyle';
|
|
3
3
|
import { IsometricOptions, IsometricRotation } from './shape/IsometricStyle';
|
|
4
4
|
import { GradientRoomsOptions } from './shape/GradientRoomsStyle';
|
|
5
|
+
import { WatercolorOptions } from './shape/WatercolorStyle';
|
|
5
6
|
export { compose, identityStyle } from './Style';
|
|
6
7
|
export type { Style, StyleContext } from './Style';
|
|
7
8
|
export { applyStyleToShapes } from './applyStyle';
|
|
@@ -25,4 +26,12 @@ export declare const SciFi: Style;
|
|
|
25
26
|
* gradient stops are recoloured per stop.
|
|
26
27
|
*/
|
|
27
28
|
export declare function GradientRooms(options?: GradientRoomsOptions): Style;
|
|
28
|
-
|
|
29
|
+
/** Stained-glass aesthetic — saturated panes framed by fat near-black leading. */
|
|
30
|
+
export declare const StainedGlass: Style;
|
|
31
|
+
/** Old-school graph-paper dungeon — pale rooms inked in navy over blue grid. */
|
|
32
|
+
export declare const GraphPaper: Style;
|
|
33
|
+
/** Topographic relief — earthy rooms with concentric contour rings. */
|
|
34
|
+
export declare const Topographic: Style;
|
|
35
|
+
/** Hand-painted watercolour — translucent edge-bled washes that pool on overlap. */
|
|
36
|
+
export declare function Watercolor(options?: WatercolorOptions): Style;
|
|
37
|
+
export type { SketchyOptions, IsometricOptions, IsometricRotation, GradientRoomsOptions, WatercolorOptions };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Style } from '../Style';
|
|
2
|
+
/**
|
|
3
|
+
* Old-school graph-paper dungeon aesthetic as a {@link Style} — the classic
|
|
4
|
+
* hand-drawn D&D look: pale rooms inked in navy over blue grid paper.
|
|
5
|
+
*
|
|
6
|
+
* - Fills map to a pale slate-blue → near-white range by luminance, so rooms
|
|
7
|
+
* stay light and the blue grid reads through. Gradient stops recolour per stop.
|
|
8
|
+
* - Strokes become fattened navy ink.
|
|
9
|
+
* - Exit lines become navy ink (kept thin where the source was thin).
|
|
10
|
+
* - Text uses navy ink.
|
|
11
|
+
* - Images and groups pass through unchanged.
|
|
12
|
+
*
|
|
13
|
+
* Pair with a cream/white background and a light-blue grid in settings for the
|
|
14
|
+
* full graph-paper effect.
|
|
15
|
+
*/
|
|
16
|
+
export declare const graphPaperShapeStyle: Style;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Style } from '../Style';
|
|
2
|
+
/**
|
|
3
|
+
* Stained-glass aesthetic as a {@link Style} — jewel-toned panes separated by
|
|
4
|
+
* thick near-black leading, glowing on a dark backdrop.
|
|
5
|
+
*
|
|
6
|
+
* - Fills are pushed to high saturation in a mid-lightness window so rooms read
|
|
7
|
+
* as coloured glass; grey rooms stay neutral (frosted panes). Gradient fills
|
|
8
|
+
* recolour per stop.
|
|
9
|
+
* - Strokes become fat near-black leading; filled panes gain leading even when
|
|
10
|
+
* the source had none.
|
|
11
|
+
* - Exit lines become slim leading too, tying the panes together.
|
|
12
|
+
* - Text uses pale glass-white for legibility over the dark cames.
|
|
13
|
+
* - Images and groups pass through unchanged.
|
|
14
|
+
*/
|
|
15
|
+
export declare const stainedGlassShapeStyle: Style;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Style } from '../Style';
|
|
2
|
+
/**
|
|
3
|
+
* Topographic / contour-map aesthetic as a {@link Style}. Rooms get an earthy
|
|
4
|
+
* elevation palette and a set of concentric inset "contour" rings, so each room
|
|
5
|
+
* reads like a hill on a shaded relief map.
|
|
6
|
+
*
|
|
7
|
+
* - Rect / circle / polygon: emit the earth-toned base shape, then up to
|
|
8
|
+
* {@link RINGS} stroke-only rings inset toward the centre. Rings collapse and
|
|
9
|
+
* are skipped for rooms too small to hold them.
|
|
10
|
+
* - Exit lines become muted brown paths.
|
|
11
|
+
* - Text uses dark sepia.
|
|
12
|
+
* - Images and groups pass through unchanged.
|
|
13
|
+
*/
|
|
14
|
+
export declare const topographicShapeStyle: Style;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Style } from '../Style';
|
|
2
|
+
export interface WatercolorOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Edge-bleed amount in map units (perpendicular wobble of pane edges).
|
|
5
|
+
* Default 0.05.
|
|
6
|
+
*/
|
|
7
|
+
bleed?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Translucent washes stacked per filled shape. More layers = deeper, more
|
|
10
|
+
* uneven colour where they overlap. Default 2 (clamped to 1..4).
|
|
11
|
+
*/
|
|
12
|
+
layers?: number;
|
|
13
|
+
/** Per-wash alpha multiplier so stacked washes build up colour. Default 0.4. */
|
|
14
|
+
alpha?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Hand-painted watercolour as a {@link Style}. Each filled shape becomes a
|
|
18
|
+
* stack of translucent, edge-wobbled washes that bleed and deepen where they
|
|
19
|
+
* overlap — soft and organic, with no crisp ink outline.
|
|
20
|
+
*
|
|
21
|
+
* - Rect / circle / polygon fills → N wobbly low-alpha polygon washes (seeded,
|
|
22
|
+
* so re-renders are identical). Hard strokes are dropped; the soft edges come
|
|
23
|
+
* from the overlapping washes.
|
|
24
|
+
* - Lines (exits) keep their colour but lose alpha so they read as a thin wet
|
|
25
|
+
* brushstroke under the rooms.
|
|
26
|
+
* - Text is repainted in muted ink.
|
|
27
|
+
* - Images and groups pass through unchanged.
|
|
28
|
+
*
|
|
29
|
+
* Unfilled stroked shapes (e.g. exit arrowheads) fall back to a single faint
|
|
30
|
+
* wobbled outline rather than vanishing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function watercolorShapeStyle(options?: WatercolorOptions): Style;
|
|
@@ -25,3 +25,8 @@ export { constructionShapeStyle } from './ConstructionStyle';
|
|
|
25
25
|
export { scifiShapeStyle } from './SciFiStyle';
|
|
26
26
|
export { gradientRoomsStyle } from './GradientRoomsStyle';
|
|
27
27
|
export type { GradientRoomsOptions } from './GradientRoomsStyle';
|
|
28
|
+
export { stainedGlassShapeStyle } from './StainedGlassStyle';
|
|
29
|
+
export { graphPaperShapeStyle } from './GraphPaperStyle';
|
|
30
|
+
export { topographicShapeStyle } from './TopographicStyle';
|
|
31
|
+
export { watercolorShapeStyle } from './WatercolorStyle';
|
|
32
|
+
export type { WatercolorOptions } from './WatercolorStyle';
|
|
@@ -23,3 +23,11 @@ export declare function parseRgb(color: string): ParsedRgb | null;
|
|
|
23
23
|
export declare function formatRgb(r: number, g: number, b: number, a?: number): string;
|
|
24
24
|
/** Perceived luminance in [0, 1] using ITU-R BT.601 weights. */
|
|
25
25
|
export declare function luminance(c: ParsedRgb): number;
|
|
26
|
+
/**
|
|
27
|
+
* Convert 0..255 RGB to HSL with hue in degrees and saturation/lightness in
|
|
28
|
+
* [0, 1]. Achromatic colours report hue 0. Shared by the newer styles
|
|
29
|
+
* (StainedGlass, …); Neon and SciFi keep their own local copies.
|
|
30
|
+
*/
|
|
31
|
+
export declare function rgbToHsl(r: number, g: number, b: number): [number, number, number];
|
|
32
|
+
/** Build an `rgb(...)` / `rgba(...)` string from HSL (hue degrees, s/l in [0,1]). */
|
|
33
|
+
export declare function hslToRgbString(h: number, s: number, l: number, a?: number): string;
|
package/dist/types/Settings.d.ts
CHANGED
|
@@ -129,10 +129,18 @@ export type HighlightStyle = {
|
|
|
129
129
|
*/
|
|
130
130
|
dashEnabled: boolean;
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
133
|
-
* (
|
|
132
|
+
* @deprecated Use {@link shape} instead. Only consulted when `shape` is
|
|
133
|
+
* `'match'` (or omitted): when true (the default) the highlight follows the
|
|
134
|
+
* current roomShape (rectangle / roundedRectangle / circle); when false it
|
|
135
|
+
* is always a circle.
|
|
134
136
|
*/
|
|
135
|
-
matchRoomShape
|
|
137
|
+
matchRoomShape?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Outline shape of the highlight. `'match'` (the default when omitted)
|
|
140
|
+
* follows the current roomShape; the other values force that specific shape
|
|
141
|
+
* regardless of the room's shape.
|
|
142
|
+
*/
|
|
143
|
+
shape?: 'match' | 'rectangle' | 'roundedRectangle' | 'circle';
|
|
136
144
|
};
|
|
137
145
|
/**
|
|
138
146
|
* Settings for map rendering.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mudlet-map-renderer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/Delwing/mudlet-map-renderer"
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"./binary": {
|
|
18
18
|
"types": "./dist/binary/index.d.ts",
|
|
19
19
|
"import": "./dist/binary.mjs"
|
|
20
|
+
},
|
|
21
|
+
"./offscreen": {
|
|
22
|
+
"types": "./dist/rendering/offscreen/index.d.ts",
|
|
23
|
+
"import": "./dist/offscreen.mjs"
|
|
20
24
|
}
|
|
21
25
|
},
|
|
22
26
|
"sideEffects": false,
|
|
@@ -25,6 +29,7 @@
|
|
|
25
29
|
"build": "tsc -p tsconfig.json && vite build",
|
|
26
30
|
"preview": "vite preview",
|
|
27
31
|
"demo:dev": "vite --config vite.demo.config.ts",
|
|
32
|
+
"bench": "vite --config vite.bench.config.ts",
|
|
28
33
|
"demo:build": "vite build --config vite.demo.config.ts",
|
|
29
34
|
"demo:preview": "vite preview --config vite.demo.config.ts",
|
|
30
35
|
"demo:headless": "tsx --tsconfig demo/tsconfig.json demo/headless.ts",
|