mudlet-map-renderer 1.2.2 → 2.1.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.
@@ -1,11 +1,12 @@
1
1
  import { default as Konva } from 'konva';
2
+ import { FillStyle } from '../scene/Shape';
2
3
  type RectCommand = {
3
4
  type: 'rect';
4
5
  x: number;
5
6
  y: number;
6
7
  w: number;
7
8
  h: number;
8
- fill?: string;
9
+ fill?: FillStyle;
9
10
  stroke?: string;
10
11
  sw: number;
11
12
  cr: number;
@@ -16,7 +17,7 @@ type CircleCommand = {
16
17
  cx: number;
17
18
  cy: number;
18
19
  r: number;
19
- fill?: string;
20
+ fill?: FillStyle;
20
21
  stroke?: string;
21
22
  sw: number;
22
23
  dash?: number[];
@@ -34,7 +35,7 @@ type LineCommand = {
34
35
  type PolygonCommand = {
35
36
  type: 'polygon';
36
37
  vertices: number[];
37
- fill?: string;
38
+ fill?: FillStyle;
38
39
  stroke?: string;
39
40
  sw: number;
40
41
  };
@@ -0,0 +1,2 @@
1
+ import { FillStyle } from '../scene/Shape';
2
+ export declare function resolveFill(ctx: CanvasRenderingContext2D, fill: FillStyle): string | CanvasGradient;
@@ -54,7 +54,6 @@ export declare class KonvaRenderBackend implements InteractiveBackend {
54
54
  private highlightShapes;
55
55
  private pathShapes;
56
56
  private currentRoomOverlay;
57
- private areaExitHitZones;
58
57
  private interactionHandler?;
59
58
  private origSetSize?;
60
59
  private cameraChangeHandler?;
@@ -94,12 +93,15 @@ export declare class KonvaRenderBackend implements InteractiveBackend {
94
93
  private clearSceneOverlayNodes;
95
94
  private subscribeToState;
96
95
  private buildScene;
97
- /** Wrap a non-group shape and walk to a recording node. */
98
- private shapeToRecordingNode;
99
96
  /**
100
- * Run the active {@link Style} over `shape`, walk every result through
101
- * {@link shapeToRecording}, and add it to `layerNode`. Returns the first
102
- * emitted node (used as the cull-tracking / destroy handle).
97
+ * Run the active {@link Style} over `shape`, walk the (possibly multi-shape)
98
+ * result into a single {@link RecordingGroupNode}, and add it to `layerNode`.
99
+ *
100
+ * Styles like Isometric expand one input shape into several (cube top + side
101
+ * faces + edges); wrapping the whole expansion into one node keeps a 1:1
102
+ * relationship between input shape and tracked handle, so callers that cache
103
+ * the return value (position marker, scene overlays, highlights, current-room
104
+ * overlay, paths) can destroy the entire expansion through that one handle.
103
105
  */
104
106
  private addStyledShape;
105
107
  /**
@@ -114,7 +116,7 @@ export declare class KonvaRenderBackend implements InteractiveBackend {
114
116
  private applyPositionMarker;
115
117
  private clearCurrentRoomOverlay;
116
118
  private updateCurrentRoomOverlay;
117
- syncHighlight(roomId: number, color: string | undefined): void;
119
+ syncHighlight(roomId: number, colors: string[] | undefined): void;
118
120
  syncHighlights(): void;
119
121
  syncPaths(): void;
120
122
  private clearOverlayShapes;
@@ -99,7 +99,12 @@ export declare class MapRenderer {
99
99
  updatePositionMarker(roomId: number): void;
100
100
  clearPosition(): void;
101
101
  centerOn(roomId: number, instant?: boolean): void;
102
- renderHighlight(roomId: number, color: string): void;
102
+ /**
103
+ * Highlight a room. Pass a single colour for the classic ring/marker, or an
104
+ * array of colours to split the highlight into that many equal pie wedges
105
+ * (one colour each).
106
+ */
107
+ renderHighlight(roomId: number, color: string | string[]): void;
103
108
  removeHighlight(roomId: number): void;
104
109
  hasHighlight(roomId: number): boolean;
105
110
  clearHighlights(): void;
@@ -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
- strokeColor: string;
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;
@@ -5,15 +5,54 @@
5
5
  * They are consumed by:
6
6
  * - {@link CullingManager} (visibility queries against a camera viewport)
7
7
  * - {@link HitTester} (point→shape lookup)
8
- * - {@link DrawCommandBuilder} (translation to engine {@link DrawCommand}s)
8
+ * - {@link buildDrawCommands} (translation to engine {@link DrawCommand}s)
9
9
  *
10
10
  * Shapes know nothing about Konva, SVG, or Canvas2D.
11
11
  */
12
12
  /** Logical layer for stacking. Mapped to engine-specific layers by renderers. */
13
13
  export type LayerId = "grid" | "link" | "room" | "position" | "overlay" | "top";
14
+ /** One gradient stop. `offset` is in 0..1; `color` is any CSS colour string. */
15
+ export interface GradientStop {
16
+ offset: number;
17
+ color: string;
18
+ }
19
+ /**
20
+ * Linear gradient between two points in the shape's LOCAL coordinate space
21
+ * (same frame as shape.x/y). Stop colours are sampled along the line
22
+ * (x0,y0) → (x1,y1).
23
+ */
24
+ export interface LinearGradient {
25
+ type: "linear";
26
+ x0: number;
27
+ y0: number;
28
+ x1: number;
29
+ y1: number;
30
+ stops: GradientStop[];
31
+ }
32
+ /**
33
+ * Radial gradient in the shape's LOCAL coordinate space. The end circle is
34
+ * (cx, cy, r); the optional start circle is (fx, fy, fr) — defaults to a
35
+ * zero-radius circle at (cx, cy) when omitted.
36
+ */
37
+ export interface RadialGradient {
38
+ type: "radial";
39
+ cx: number;
40
+ cy: number;
41
+ r: number;
42
+ fx?: number;
43
+ fy?: number;
44
+ fr?: number;
45
+ stops: GradientStop[];
46
+ }
47
+ /** A fill is either a flat colour string or a gradient. */
48
+ export type FillStyle = string | LinearGradient | RadialGradient;
14
49
  /** Engine-agnostic paint description. */
15
50
  export interface Paint {
16
- fill?: string;
51
+ /**
52
+ * Colour string (`#rrggbb`, `rgb(...)`, named colour) or a gradient.
53
+ * Gradient coords are in the same local frame as the shape's geometry.
54
+ */
55
+ fill?: FillStyle;
17
56
  stroke?: string;
18
57
  strokeWidth?: number;
19
58
  dash?: number[];
@@ -21,6 +60,21 @@ export interface Paint {
21
60
  /** 0..1 multiplier on fill+stroke. */
22
61
  alpha?: number;
23
62
  }
63
+ /** True when `fill` is a gradient object rather than a colour string. */
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;
72
+ /**
73
+ * Apply a camera-style affine (translate by world origin, scale uniformly,
74
+ * translate by render offset) to a fill. Strings pass through unchanged.
75
+ * Gradient stops are colour-only and never transformed.
76
+ */
77
+ export declare function transformFill(fill: FillStyle | undefined, worldX: number, worldY: number, scale: number, offsetX: number, offsetY: number): FillStyle | undefined;
24
78
  /** Hit-test annotation. Set on shapes that should be pickable. */
25
79
  export interface HitInfo {
26
80
  /** What the shape represents at the model layer. */
@@ -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. */
@@ -1,6 +1,7 @@
1
1
  import { Style } from './Style';
2
2
  import { SketchyOptions } from './shape/SketchyStyle';
3
3
  import { IsometricOptions, IsometricRotation } from './shape/IsometricStyle';
4
+ import { GradientRoomsOptions } from './shape/GradientRoomsStyle';
4
5
  export { compose, identityStyle } from './Style';
5
6
  export type { Style, StyleContext } from './Style';
6
7
  export { applyStyleToShapes } from './applyStyle';
@@ -18,4 +19,10 @@ export declare function Isometric(options?: IsometricOptions): Style;
18
19
  export declare const Construction: Style;
19
20
  /** Sci-fi / space-exploration aesthetic — holographic cyan glow on void black. */
20
21
  export declare const SciFi: Style;
21
- export type { SketchyOptions, IsometricOptions, IsometricRotation };
22
+ /**
23
+ * Replace flat room fills with a vertical linear gradient (lighter top,
24
+ * darker bottom). Compose with palette styles to keep their tones — the
25
+ * gradient stops are recoloured per stop.
26
+ */
27
+ export declare function GradientRooms(options?: GradientRoomsOptions): Style;
28
+ export type { SketchyOptions, IsometricOptions, IsometricRotation, GradientRoomsOptions };
@@ -0,0 +1,23 @@
1
+ import { Style } from '../Style';
2
+ export interface GradientRoomsOptions {
3
+ /**
4
+ * How much to lighten the top stop relative to the room's solid fill.
5
+ * Default 0.35. Set to 0 to keep the top edge unchanged.
6
+ */
7
+ lighten?: number;
8
+ /**
9
+ * How much to darken the bottom stop. Default 0.25.
10
+ */
11
+ darken?: number;
12
+ }
13
+ /**
14
+ * Replace each rect/circle/polygon's flat fill with a vertical linear
15
+ * gradient: lightened version of the fill at the top, darkened version at
16
+ * the bottom. Gives rooms a faux-3D shaded look. Strokes and other paint
17
+ * fields pass through.
18
+ *
19
+ * When composed with palette styles (Parchment, Blueprint, …) the gradient
20
+ * stops are recoloured by the downstream style — so `compose(Parchment,
21
+ * GradientRooms)` produces parchment-toned gradients, not flat parchment.
22
+ */
23
+ export declare function gradientRoomsStyle(options?: GradientRoomsOptions): Style;
@@ -23,3 +23,5 @@ export { isometricShapeStyle } from './IsometricStyle';
23
23
  export type { IsometricOptions, IsometricRotation } from './IsometricStyle';
24
24
  export { constructionShapeStyle } from './ConstructionStyle';
25
25
  export { scifiShapeStyle } from './SciFiStyle';
26
+ export { gradientRoomsStyle } from './GradientRoomsStyle';
27
+ export type { GradientRoomsOptions } from './GradientRoomsStyle';
@@ -1,11 +1,11 @@
1
+ import { FillStyle } from '../../scene/Shape';
1
2
  /**
2
- * Shared colour-parsing + paint-rewriting helpers used by the shape-based
3
- * Style implementations (Parchment, Blueprint, Neon).
4
- *
5
- * The old BaseStyle decorator versions in `../ParchmentStyle.ts`,
6
- * `../BlueprintStyle.ts`, and `../NeonStyle.ts` keep their own copies for
7
- * now; they're deleted in step 11.
3
+ * Apply a colour-mapping function to a {@link FillStyle}. Strings pass
4
+ * through the mapper directly; gradients recolour every stop, leaving
5
+ * geometry untouched. Lets styles tint gradient-filled rooms (ambient
6
+ * lighting, palette swaps) without losing the gradient.
8
7
  */
8
+ export declare function mapFill(fill: FillStyle | undefined, mapper: (color: string) => string): FillStyle | undefined;
9
9
  export interface ParsedRgb {
10
10
  r: number;
11
11
  g: number;
@@ -129,10 +129,18 @@ export type HighlightStyle = {
129
129
  */
130
130
  dashEnabled: boolean;
131
131
  /**
132
- * When true, the highlight shape matches the current roomShape setting
133
- * (rectangle, circle, or roundedRectangle). When false, the highlight is always a circle.
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: boolean;
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": "1.2.2",
3
+ "version": "2.1.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "url": "https://github.com/Delwing/mudlet-map-renderer"