@tomtom-org/maps-sdk-plugin-map-effects 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ THIRD-PARTY SOFTWARE NOTICES FOR @tomtom-org/maps-sdk-plugin-map-effects
2
+
3
+ This file lists the third-party components used by this package, together with
4
+ their licenses. It is generated from the build output — do not edit it by hand.
5
+
6
+ Components marked "Bundled: false (peer dependency)" are not shipped inside it:
7
+ your package manager installs them alongside it and your application bundles them.
8
+ The licenses below apply to those copies, and each such component may in turn install
9
+ its own dependencies under their own licenses.
10
+
11
+ The software itself is licensed under the terms in LICENSE.txt, which is not affected
12
+ by the licenses reproduced here.
13
+
14
+ --------------------------------------------------------------------------------
15
+
16
+ Name: maplibre-gl
17
+ Version: 6.9.0
18
+ License: BSD-3-Clause
19
+ Bundled: false (peer dependency)
20
+ Description: BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
21
+ Repository: https://github.com/maplibre/maplibre-gl-js
22
+ Homepage: https://maplibre.org/
23
+ License Text:
24
+ ===
25
+
26
+ Copyright (c) 2023, MapLibre contributors
27
+
28
+ All rights reserved.
29
+
30
+ Redistribution and use in source and binary forms, with or without modification,
31
+ are permitted provided that the following conditions are met:
32
+
33
+ * Redistributions of source code must retain the above copyright notice,
34
+ this list of conditions and the following disclaimer.
35
+ * Redistributions in binary form must reproduce the above copyright notice,
36
+ this list of conditions and the following disclaimer in the documentation
37
+ and/or other materials provided with the distribution.
38
+ * Neither the name of MapLibre GL JS nor the names of its contributors
39
+ may be used to endorse or promote products derived from this software
40
+ without specific prior written permission.
41
+
42
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
46
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
48
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
49
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
50
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
51
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53
+
54
+
55
+ -------------------------------------------------------------------------------
56
+
57
+ Contains code from mapbox-gl-js v1.13 and earlier
58
+
59
+ Version v1.13 of mapbox-gl-js and earlier are licensed under a BSD-3-Clause license
60
+
61
+ Copyright (c) 2020, Mapbox
62
+ Redistribution and use in source and binary forms, with or without modification,
63
+ are permitted provided that the following conditions are met:
64
+
65
+ * Redistributions of source code must retain the above copyright notice,
66
+ this list of conditions and the following disclaimer.
67
+ * Redistributions in binary form must reproduce the above copyright notice,
68
+ this list of conditions and the following disclaimer in the documentation
69
+ and/or other materials provided with the distribution.
70
+ * Neither the name of Mapbox GL JS nor the names of its contributors
71
+ may be used to endorse or promote products derived from this software
72
+ without specific prior written permission.
73
+
74
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
75
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
76
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
77
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
78
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
79
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
80
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
81
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
82
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
83
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
84
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85
+
86
+
87
+ -------------------------------------------------------------------------------
88
+
89
+ Contains code from glfx.js
90
+
91
+ Copyright (C) 2011 by Evan Wallace
92
+
93
+ Permission is hereby granted, free of charge, to any person obtaining a copy
94
+ of this software and associated documentation files (the "Software"), to deal
95
+ in the Software without restriction, including without limitation the rights
96
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
97
+ copies of the Software, and to permit persons to whom the Software is
98
+ furnished to do so, subject to the following conditions:
99
+
100
+ The above copyright notice and this permission notice shall be included in
101
+ all copies or substantial portions of the Software.
102
+
103
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
104
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
105
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
106
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
107
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
108
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
109
+ THE SOFTWARE.
110
+
111
+ --------------------------------------------------------------------------------
112
+
113
+ Contains a portion of d3-color https://github.com/d3/d3-color
114
+
115
+ Copyright 2010-2016 Mike Bostock
116
+ All rights reserved.
117
+
118
+ Redistribution and use in source and binary forms, with or without modification,
119
+ are permitted provided that the following conditions are met:
120
+
121
+ * Redistributions of source code must retain the above copyright notice, this
122
+ list of conditions and the following disclaimer.
123
+
124
+ * Redistributions in binary form must reproduce the above copyright notice,
125
+ this list of conditions and the following disclaimer in the documentation
126
+ and/or other materials provided with the distribution.
127
+
128
+ * Neither the name of the author nor the names of contributors may be used to
129
+ endorse or promote products derived from this software without specific prior
130
+ written permission.
131
+
132
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
133
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
134
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
136
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
137
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
138
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
139
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
140
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142
+
@@ -0,0 +1,131 @@
1
+ The following third-party components are declared as peer dependencies. Their code is
2
+ NOT bundled into this package: your package manager installs them alongside it and
3
+ your application bundles them. The licenses below apply to those copies, and each of
4
+ these components may in turn install its own dependencies under their own licenses.
5
+
6
+ Name: maplibre-gl
7
+ Version: 6.9.0
8
+ License: BSD-3-Clause
9
+ Bundled: false (peer dependency)
10
+ Description: BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
11
+ Repository: https://github.com/maplibre/maplibre-gl-js
12
+ Homepage: https://maplibre.org/
13
+ License Text:
14
+ ===
15
+
16
+ Copyright (c) 2023, MapLibre contributors
17
+
18
+ All rights reserved.
19
+
20
+ Redistribution and use in source and binary forms, with or without modification,
21
+ are permitted provided that the following conditions are met:
22
+
23
+ * Redistributions of source code must retain the above copyright notice,
24
+ this list of conditions and the following disclaimer.
25
+ * Redistributions in binary form must reproduce the above copyright notice,
26
+ this list of conditions and the following disclaimer in the documentation
27
+ and/or other materials provided with the distribution.
28
+ * Neither the name of MapLibre GL JS nor the names of its contributors
29
+ may be used to endorse or promote products derived from this software
30
+ without specific prior written permission.
31
+
32
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
38
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
39
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
40
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
+
44
+
45
+ -------------------------------------------------------------------------------
46
+
47
+ Contains code from mapbox-gl-js v1.13 and earlier
48
+
49
+ Version v1.13 of mapbox-gl-js and earlier are licensed under a BSD-3-Clause license
50
+
51
+ Copyright (c) 2020, Mapbox
52
+ Redistribution and use in source and binary forms, with or without modification,
53
+ are permitted provided that the following conditions are met:
54
+
55
+ * Redistributions of source code must retain the above copyright notice,
56
+ this list of conditions and the following disclaimer.
57
+ * Redistributions in binary form must reproduce the above copyright notice,
58
+ this list of conditions and the following disclaimer in the documentation
59
+ and/or other materials provided with the distribution.
60
+ * Neither the name of Mapbox GL JS nor the names of its contributors
61
+ may be used to endorse or promote products derived from this software
62
+ without specific prior written permission.
63
+
64
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
65
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
66
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
67
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
68
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
69
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
70
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
71
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
72
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
73
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
74
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75
+
76
+
77
+ -------------------------------------------------------------------------------
78
+
79
+ Contains code from glfx.js
80
+
81
+ Copyright (C) 2011 by Evan Wallace
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining a copy
84
+ of this software and associated documentation files (the "Software"), to deal
85
+ in the Software without restriction, including without limitation the rights
86
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
87
+ copies of the Software, and to permit persons to whom the Software is
88
+ furnished to do so, subject to the following conditions:
89
+
90
+ The above copyright notice and this permission notice shall be included in
91
+ all copies or substantial portions of the Software.
92
+
93
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
96
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
98
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
99
+ THE SOFTWARE.
100
+
101
+ --------------------------------------------------------------------------------
102
+
103
+ Contains a portion of d3-color https://github.com/d3/d3-color
104
+
105
+ Copyright 2010-2016 Mike Bostock
106
+ All rights reserved.
107
+
108
+ Redistribution and use in source and binary forms, with or without modification,
109
+ are permitted provided that the following conditions are met:
110
+
111
+ * Redistributions of source code must retain the above copyright notice, this
112
+ list of conditions and the following disclaimer.
113
+
114
+ * Redistributions in binary form must reproduce the above copyright notice,
115
+ this list of conditions and the following disclaimer in the documentation
116
+ and/or other materials provided with the distribution.
117
+
118
+ * Neither the name of the author nor the names of contributors may be used to
119
+ endorse or promote products derived from this software without specific prior
120
+ written permission.
121
+
122
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
123
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
126
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
129
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,322 @@
1
+ import { KnobDescriptor, KnobRange, TomTomMap } from "@tomtom-org/maps-sdk/map";
2
+ //#region src/effectsCatalogue.d.ts
3
+ /**
4
+ * The range of a numeric effect knob. Every one ships a slider `step`; the shared {@link KnobRange}
5
+ * leaves it optional.
6
+ *
7
+ * @group Map Effects
8
+ */
9
+ type EffectKnobRange = KnobRange & {
10
+ step: number;
11
+ };
12
+ /**
13
+ * The effects catalogue. Every effect is off at its default; each is named by the product problem it
14
+ * solves. Ordering is the compositing order: bloom → grade → fog → edge blur → tint → vignette.
15
+ * @ignore
16
+ */
17
+ declare const effectKnobDefinitions: {
18
+ readonly 'bloom.intensity': {
19
+ readonly kind: "number";
20
+ readonly description: "How strongly bright features (lit roads, traffic tubes, route lines) glow. 0 = off.";
21
+ readonly default: 0;
22
+ readonly range: EffectKnobRange;
23
+ readonly useCase: "Emphasis on dark and driving styles.";
24
+ };
25
+ readonly 'bloom.radius': {
26
+ readonly kind: "number";
27
+ readonly description: "How far the glow spreads, in CSS pixels.";
28
+ readonly default: 12;
29
+ readonly range: {
30
+ readonly min: 2;
31
+ readonly max: 40;
32
+ readonly step: 1;
33
+ };
34
+ readonly useCase: "Emphasis on dark and driving styles.";
35
+ };
36
+ readonly 'bloom.threshold': {
37
+ readonly kind: "number";
38
+ readonly description: "Brightness below which nothing glows. Raise it so only the brightest features light up.";
39
+ readonly default: 0.55;
40
+ readonly range: EffectKnobRange;
41
+ readonly useCase: "Emphasis on dark and driving styles.";
42
+ };
43
+ readonly 'grade.brightness': {
44
+ readonly kind: "number";
45
+ readonly description: "Brightness of the whole base map (1 = unchanged).";
46
+ readonly default: 1;
47
+ readonly range: {
48
+ readonly min: 0.5;
49
+ readonly max: 1.5;
50
+ readonly step: 0.05;
51
+ };
52
+ readonly useCase: "Muting the base map under a data overlay.";
53
+ };
54
+ readonly 'grade.contrast': {
55
+ readonly kind: "number";
56
+ readonly description: "Contrast of the whole base map (1 = unchanged).";
57
+ readonly default: 1;
58
+ readonly range: {
59
+ readonly min: 0.5;
60
+ readonly max: 1.5;
61
+ readonly step: 0.05;
62
+ };
63
+ readonly useCase: "Muting the base map under a data overlay.";
64
+ };
65
+ readonly 'grade.saturation': {
66
+ readonly kind: "number";
67
+ readonly description: "Colour saturation of the whole base map (1 = unchanged, 0 = greyscale).";
68
+ readonly default: 1;
69
+ readonly range: {
70
+ readonly min: 0;
71
+ readonly max: 1.5;
72
+ readonly step: 0.05;
73
+ };
74
+ readonly useCase: "Muting the base map under a data overlay.";
75
+ };
76
+ readonly 'fog.intensity': {
77
+ readonly kind: "number";
78
+ readonly description: "Haze over the edges of the view: blur, plus a wash towards the colour of the air — pale on a light map, dark on a dark one. Reads as distance. 0 = off.";
79
+ readonly default: 0;
80
+ readonly range: EffectKnobRange;
81
+ readonly useCase: "Depth cue: the far context recedes as if seen through air.";
82
+ };
83
+ readonly 'fog.reach': {
84
+ readonly kind: "number";
85
+ readonly description: "How far the fog reaches in from the edges (1 = to the centre).";
86
+ readonly default: 0.4;
87
+ readonly range: EffectKnobRange;
88
+ readonly useCase: "Depth cue: the far context recedes as if seen through air.";
89
+ };
90
+ readonly 'edgeBlur.intensity': {
91
+ readonly kind: "number";
92
+ readonly description: "Blur over the edges of the view, in CSS pixels, leaving their colour untouched. Reads as a lens, not as distance — `fog` is the effect that also washes the rim out. 0 = off.";
93
+ readonly default: 0;
94
+ readonly range: {
95
+ readonly min: 0;
96
+ readonly max: 30;
97
+ readonly step: 1;
98
+ };
99
+ readonly useCase: "Focus: the centre stays sharp and the edges lose their detail.";
100
+ };
101
+ readonly 'edgeBlur.reach': {
102
+ readonly kind: "number";
103
+ readonly description: "How far the edge blur reaches in from the edges (1 = to the centre).";
104
+ readonly default: 0.5;
105
+ readonly range: EffectKnobRange;
106
+ readonly useCase: "Focus: the centre stays sharp and the edges lose their detail.";
107
+ };
108
+ readonly 'tint.color': {
109
+ readonly kind: "color";
110
+ readonly description: "A flat colour laid over the whole map.";
111
+ readonly default: "#1f2937";
112
+ readonly useCase: "Muting the base map under a data overlay; matching a brand.";
113
+ };
114
+ readonly 'tint.opacity': {
115
+ readonly kind: "number";
116
+ readonly description: "Opacity of the tint. 0 = off.";
117
+ readonly default: 0;
118
+ readonly range: EffectKnobRange;
119
+ readonly useCase: "Muting the base map under a data overlay; matching a brand.";
120
+ };
121
+ readonly 'vignette.intensity': {
122
+ readonly kind: "number";
123
+ readonly description: "Darkening (negative) or lightening (positive) towards the edges. 0 = off.";
124
+ readonly default: 0;
125
+ readonly range: {
126
+ readonly min: -1;
127
+ readonly max: 1;
128
+ readonly step: 0.05;
129
+ };
130
+ readonly useCase: "Focus on the centre of the view.";
131
+ };
132
+ readonly 'vignette.reach': {
133
+ readonly kind: "number";
134
+ readonly description: "How far the vignette reaches in from the edges (1 = to the centre).";
135
+ readonly default: 0.45;
136
+ readonly range: EffectKnobRange;
137
+ readonly useCase: "Focus on the centre of the view.";
138
+ };
139
+ };
140
+ /**
141
+ * The id of an effect knob, as accepted by {@link MapEffects.set}.
142
+ *
143
+ * @group Map Effects
144
+ */
145
+ type EffectKnobId = keyof typeof effectKnobDefinitions;
146
+ /**
147
+ * Every effect knob id, in compositing order.
148
+ *
149
+ * @group Map Effects
150
+ */
151
+ export declare const effectKnobIds: EffectKnobId[];
152
+ /**
153
+ * The value type an effect knob takes.
154
+ *
155
+ * @group Map Effects
156
+ */
157
+ type EffectKnobValueOf<ID extends EffectKnobId> = (typeof effectKnobDefinitions)[ID]['kind'] extends 'color' ? string : number;
158
+ //#endregion
159
+ //#region src/MapEffects.d.ts
160
+ /**
161
+ * The effect knob values an app sets — only the overridden ones, serializable like the SDK's
162
+ * styling settings.
163
+ *
164
+ * @group Map Effects
165
+ */
166
+ type MapEffectsSettings = { [ID in EffectKnobId]?: EffectKnobValueOf<ID>; };
167
+ /**
168
+ * One entry of the effects catalogue: the SDK's shared {@link KnobDescriptor}, narrowed the way
169
+ * `StylingKnobDescriptor` narrows it, plus the use case the effect serves.
170
+ *
171
+ * @group Map Effects
172
+ */
173
+ type MapEffectsKnobDescriptor = KnobDescriptor<number | string> & {
174
+ /** The knob's id, as accepted by {@link MapEffects.set}. */
175
+ id: EffectKnobId;
176
+ /** The range of valid values, for every knob but `tint.color`. */
177
+ range?: EffectKnobRange;
178
+ /** Always `true`: an effect reads the rendered pixels, so it has something to work on anywhere. */
179
+ available: boolean;
180
+ /** Always `any-style`, for the same reason. */
181
+ appliesTo: string;
182
+ /** The practical problem the effect solves. */
183
+ useCase: string;
184
+ };
185
+ /**
186
+ * The effects catalogue, in the same shape as `StylingModule.describe()` so one control panel or
187
+ * agent tool can drive both.
188
+ *
189
+ * @group Map Effects
190
+ */
191
+ type MapEffectsCatalogue = {
192
+ knobs: MapEffectsKnobDescriptor[];
193
+ };
194
+ /**
195
+ * Options for {@link MapEffects.capture}.
196
+ *
197
+ * @group Map Effects
198
+ */
199
+ type CaptureOptions = {
200
+ /**
201
+ * Device pixels per CSS pixel to render at. Defaults to the map's current ratio; `2` or `3` gives
202
+ * a print-grade capture of the same view. MapLibre clamps to its `maxCanvasSize`, so measure the
203
+ * ratio you got from the returned canvas rather than assuming.
204
+ */
205
+ pixelRatio?: number;
206
+ };
207
+ /**
208
+ * Practical post-processing for a {@link TomTomMap}: effects computed from the rendered map's own
209
+ * pixels, not from its style — so they work on every style, custom ones included, survive every
210
+ * style release, and cannot be reproduced by editing the style at all.
211
+ *
212
+ * @remarks
213
+ * Every effect is named by the problem it solves, and off by default:
214
+ * - **bloom** — emphasis on dark and driving styles: lit roads, traffic tubes and route lines glow;
215
+ * - **grade** (brightness, contrast, saturation) and **tint** — muting the base map so a data overlay
216
+ * reads first;
217
+ * - **fog** — depth: the rim is blurred *and* washed towards the colour of the air, which follows the
218
+ * map's light/dark theme;
219
+ * - **edge blur** — focus: the rim is blurred and keeps its colour, so it reads as a lens rather than
220
+ * as distance;
221
+ * - **vignette** — focus too, by darkening or lightening the edges.
222
+ *
223
+ * Effects render live as layers over the map canvas (`backdrop-filter` overlays; bloom is a small
224
+ * canvas blended in `screen` mode) and are composited the same way into {@link capture}, so what is
225
+ * captured is what was on screen. Bloom and capture read the map canvas, which needs
226
+ * `mapLibre: { canvasContextAttributes: { preserveDrawingBuffer: true } }` when creating the map;
227
+ * the plugin warns once when it is missing.
228
+ *
229
+ * {@link describe} returns the knobs in the same shape as `StylingModule.describe()`, so a control
230
+ * panel or an agent tool built for the SDK's styling catalogue reads this one unchanged.
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * import { MapEffects } from '@tomtom-org/maps-sdk-plugin-map-effects';
235
+ *
236
+ * const effects = new MapEffects(map);
237
+ * // The data-viz muting half: a dim, desaturated base under your own layers.
238
+ * effects.set({ 'grade.saturation': 0.4, 'grade.brightness': 0.85, 'tint.opacity': 0.15 });
239
+ * // Night-driving emphasis on a dark style:
240
+ * effects.set({ 'bloom.intensity': 0.5, 'bloom.threshold': 0.6 });
241
+ *
242
+ * const poster = await effects.capture({ pixelRatio: 3 });
243
+ * ```
244
+ *
245
+ * @group Map Effects
246
+ */
247
+ export declare class MapEffects {
248
+ private readonly map;
249
+ private settings;
250
+ private readonly container;
251
+ private readonly overlays;
252
+ private readonly bloomCanvas;
253
+ private bloomFrame;
254
+ private warnedBuffer;
255
+ private readonly onRender;
256
+ /**
257
+ * Attaches the effects to a map. Nothing is visible until {@link set} turns an effect on.
258
+ *
259
+ * @param map - The map to render effects over.
260
+ * @param settings - Effect knob values to apply right away.
261
+ */
262
+ constructor(map: TomTomMap, settings?: MapEffectsSettings);
263
+ /**
264
+ * Sets one or more effect knobs. Values are validated against the catalogue before anything is
265
+ * touched; knobs not mentioned keep their values.
266
+ *
267
+ * @param settings - Knob id → value.
268
+ * @throws `RangeError` for a value outside its range or of the wrong kind; `Error` for an unknown id.
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * effects.set({ 'vignette.intensity': -0.4 });
273
+ * ```
274
+ */
275
+ set(settings: MapEffectsSettings): void;
276
+ /**
277
+ * The current value of a knob: the override, or the catalogue default.
278
+ */
279
+ get<ID extends EffectKnobId>(id: ID): EffectKnobValueOf<ID>;
280
+ /**
281
+ * Turns a knob (or every knob) back to its default — for most effects, off.
282
+ */
283
+ reset(id?: EffectKnobId): void;
284
+ /**
285
+ * The overridden knobs, as a plain serializable object.
286
+ */
287
+ getConfig(): MapEffectsSettings;
288
+ /**
289
+ * Replaces every knob with the given settings (an empty object turns everything off).
290
+ */
291
+ applyConfig(settings: MapEffectsSettings): void;
292
+ /**
293
+ * The effects catalogue: every knob with kind, range, default, current value and the practical
294
+ * use case it serves. Same descriptor shape as `StylingModule.describe()`.
295
+ */
296
+ describe(): MapEffectsCatalogue;
297
+ /**
298
+ * Renders the current view — map and effects — into a canvas, optionally at a higher pixel ratio
299
+ * for print. The map is re-rendered at that ratio (never resampled), read back once every tile is
300
+ * drawn, and restored to follow the device afterwards.
301
+ *
302
+ * @remarks
303
+ * Needs `preserveDrawingBuffer: true` on the map's canvas context; without it the map half of the
304
+ * capture is blank. Viewers cannot download from a sandboxed page, so hand the canvas to your own
305
+ * upload or `toBlob` flow.
306
+ */
307
+ capture(options?: CaptureOptions): Promise<HTMLCanvasElement>;
308
+ /**
309
+ * Detaches the effects from the map and removes their elements.
310
+ */
311
+ remove(): void;
312
+ private render;
313
+ private scheduleBloom;
314
+ private drawBloom;
315
+ private readBack;
316
+ private settled;
317
+ private warnIfBufferNotPreserved;
318
+ private assertKnob;
319
+ private validate;
320
+ }
321
+ //#endregion
322
+ export type { CaptureOptions, EffectKnobId, EffectKnobRange, EffectKnobValueOf, MapEffectsCatalogue, MapEffectsKnobDescriptor, MapEffectsSettings };
@@ -0,0 +1,2 @@
1
+ import{knob as e}from"@tomtom-org/maps-sdk/map";var t={min:0,max:1,step:.05},n="Emphasis on dark and driving styles.",a="Muting the base map under a data overlay.",i="Depth cue: the far context recedes as if seen through air.",s="Focus: the centre stays sharp and the edges lose their detail.",r="Muting the base map under a data overlay; matching a brand.",o="Focus on the centre of the view.",l={"bloom.intensity":{kind:"number",description:"How strongly bright features (lit roads, traffic tubes, route lines) glow. 0 = off.",default:0,range:t,useCase:n},"bloom.radius":{kind:"number",description:"How far the glow spreads, in CSS pixels.",default:12,range:{min:2,max:40,step:1},useCase:n},"bloom.threshold":{kind:"number",description:"Brightness below which nothing glows. Raise it so only the brightest features light up.",default:.55,range:t,useCase:n},"grade.brightness":{kind:"number",description:"Brightness of the whole base map (1 = unchanged).",default:1,range:{min:.5,max:1.5,step:.05},useCase:a},"grade.contrast":{kind:"number",description:"Contrast of the whole base map (1 = unchanged).",default:1,range:{min:.5,max:1.5,step:.05},useCase:a},"grade.saturation":{kind:"number",description:"Colour saturation of the whole base map (1 = unchanged, 0 = greyscale).",default:1,range:{min:0,max:1.5,step:.05},useCase:a},"fog.intensity":{kind:"number",description:"Haze over the edges of the view: blur, plus a wash towards the colour of the air — pale on a light map, dark on a dark one. Reads as distance. 0 = off.",default:0,range:t,useCase:i},"fog.reach":{kind:"number",description:"How far the fog reaches in from the edges (1 = to the centre).",default:.4,range:t,useCase:i},"edgeBlur.intensity":{kind:"number",description:"Blur over the edges of the view, in CSS pixels, leaving their colour untouched. Reads as a lens, not as distance — `fog` is the effect that also washes the rim out. 0 = off.",default:0,range:{min:0,max:30,step:1},useCase:s},"edgeBlur.reach":{kind:"number",description:"How far the edge blur reaches in from the edges (1 = to the centre).",default:.5,range:t,useCase:s},"tint.color":{kind:"color",description:"A flat colour laid over the whole map.",default:"#1f2937",useCase:r},"tint.opacity":{kind:"number",description:"Opacity of the tint. 0 = off.",default:0,range:t,useCase:r},"vignette.intensity":{kind:"number",description:"Darkening (negative) or lightening (positive) towards the edges. 0 = off.",default:0,range:{min:-1,max:1,step:.05},useCase:o},"vignette.reach":{kind:"number",description:"How far the vignette reaches in from the edges (1 = to the centre).",default:.45,range:t,useCase:o}},h=Object.keys(l),d=e=>Math.min(Math.max(e,0),1),g=(e,t,n=1)=>{const a=.92*d(t),i=(1+a)/(1-a);return`brightness(${(1/(1+a)).toFixed(4)}) contrast(${i.toFixed(3)}) blur(${e*n}px) saturate(1.35)`},c=(e,t,n)=>[1===e?"":`brightness(${e})`,1===t?"":`contrast(${t})`,1===n?"":`saturate(${n})`].filter(Boolean).join(" "),m=(e,t,n)=>`radial-gradient(ellipse farthest-corner at center, ${e} ${Math.round(100*(1-d(n)))}%, ${t} 100%)`,u=(e,t)=>{const{inner:n,outer:a}=b(e);return m(n,a,t)},b=e=>{const t=e<0?"0, 0, 0":"255, 255, 255";return{inner:`rgba(${t}, 0)`,outer:`rgba(${t}, ${Math.min(Math.abs(e),1)})`}},f=e=>m("transparent","black",e),p={light:{rgb:"238, 240, 244",grade:"brightness(1.08) contrast(0.82) saturate(0.7)"},dark:{rgb:"16, 22, 33",grade:"brightness(0.92) contrast(0.82) saturate(0.7)"}},v="saturate(1.08)",w=e=>p[e].grade,y=e=>2+6*e,C=(e,t)=>`blur(${y(e)}px) ${w(t)}`,k=(e,t)=>{const{rgb:n}=p[t];return{inner:`rgba(${n}, 0)`,outer:`rgba(${n}, ${.65*e})`}},x=(e,t,n)=>{const{inner:a,outer:i}=k(e,n);return m(a,i,t)},B=(e,t,n,a)=>{const i=document.createElement("canvas");i.width=t,i.height=n;const s=i.getContext("2d");if(s)return s.filter=a,s.drawImage(e.canvas,0,0),s.filter="none",s},$=(e,t,n,a=1)=>{e.save(),e.globalCompositeOperation=n,e.globalAlpha=a,e.drawImage(t.canvas,0,0),e.restore()},M=(e,t,n,a,i,s)=>{const r=t/Math.SQRT2,o=n/Math.SQRT2,l=e.createRadialGradient(0,0,1-a,0,0,1);l.addColorStop(0,i),l.addColorStop(1,s),e.save(),e.translate(t/2,n/2),e.scale(r,o),e.fillStyle=l,e.fillRect(-t/2/r,-n/2/o,t/r,n/o),e.restore()},R=(e,t,n,a,i,s,r)=>{const o=B(e,t,n,`blur(${i*a}px) ${r}`.trim());o&&(o.globalCompositeOperation="destination-in",M(o,t,n,s,"rgba(0,0,0,0)","rgba(0,0,0,1)"),e.drawImage(o.canvas,0,0))},S=(e,t,n,a,i,s)=>{i["bloom.intensity"]>0&&((e,t,n,a,i)=>{const s=g(i["bloom.radius"],i["bloom.threshold"],a),r=B(e,t,n,s);r&&$(e,r,"screen",i["bloom.intensity"])})(e,t,n,a,i);const r=c(i["grade.brightness"],i["grade.contrast"],i["grade.saturation"]);if(r&&((e,t,n,a)=>{const i=B(e,t,n,a);i&&$(e,i,"copy")})(e,t,n,r),i["fog.intensity"]>0){const r=i["fog.intensity"],o=i["fog.reach"],{inner:l,outer:h}=k(r,s);R(e,t,n,a,y(r),o,w(s)),M(e,t,n,o,l,h)}if(i["edgeBlur.intensity"]>0&&R(e,t,n,a,i["edgeBlur.intensity"],i["edgeBlur.reach"],v),i["tint.opacity"]>0&&(e.save(),e.globalAlpha=i["tint.opacity"],e.fillStyle=i["tint.color"],e.fillRect(0,0,t,n),e.restore()),0!==i["vignette.intensity"]){const{inner:a,outer:s}=b(i["vignette.intensity"]);M(e,t,n,i["vignette.reach"],a,s)}},E=e=>Object.fromEntries(h.map(t=>[t,e[t]??l[t].default])),F=["bloom","grade","fog","edgeBlur","tint","vignette"],I=e=>({backdropFilter:e,webkitBackdropFilter:e}),L=e=>({maskImage:e,webkitMaskImage:e}),O=class{map;settings={};container;overlays;bloomCanvas;bloomFrame;warnedBuffer=!1;onRender=()=>this.scheduleBloom();constructor(e,t={}){this.map=e;const n=this.map.mapLibreMap.getContainer();this.container=document.createElement("div"),this.container.className="tomtom-map-effects",Object.assign(this.container.style,{position:"absolute",inset:"0",pointerEvents:"none",overflow:"hidden"}),n.querySelector(".maplibregl-canvas-container")?.insertAdjacentElement("afterend",this.container)??n.appendChild(this.container),this.bloomCanvas=document.createElement("canvas"),this.overlays=Object.fromEntries(F.map(e=>{const t="bloom"===e?this.bloomCanvas:document.createElement("div");return t.dataset.effect=e,Object.assign(t.style,{position:"absolute",inset:"0",width:"100%",height:"100%",pointerEvents:"none",display:"none"}),this.container.appendChild(t),[e,t]})),this.bloomCanvas.style.mixBlendMode="screen",this.map.mapLibreMap.on("render",this.onRender),this.set(t)}set(e){for(const[t,n]of Object.entries(e))this.validate(t,n);this.settings={...this.settings,...e},this.render()}get(e){return this.assertKnob(e),this.settings[e]??l[e].default}reset(e){if(void 0===e)this.settings={};else{this.assertKnob(e);const{[e]:t,...n}=this.settings;this.settings=n}this.render()}getConfig(){return{...this.settings}}applyConfig(e){this.settings={},this.set(e)}describe(){return{knobs:h.map(t=>{const n=l[t];return e(t,n.kind,n.description,n.default,this.settings[t],{..."range"in n&&{range:n.range},available:!0,appliesTo:"any-style",useCase:n.useCase})})}}async capture(e={}){this.warnIfBufferNotPreserved();const t=this.map.mapLibreMap,n=t,a=t.getPixelRatio(),i=e.pixelRatio??a,s=a!==(globalThis.devicePixelRatio||1),r=Math.abs(i-a)>.01;r&&(n.setPixelRatio(i),await this.settled());try{return await this.readBack()}finally{r&&n.setPixelRatio(s?a:null)}}remove(){this.map.mapLibreMap.off("render",this.onRender),void 0!==this.bloomFrame&&cancelAnimationFrame(this.bloomFrame),this.container.remove()}render(){const e=E(this.settings),t=(e,t,n={})=>{const a=this.overlays[e];a.style.display=t?"block":"none",Object.assign(a.style,n)},n=c(e["grade.brightness"],e["grade.contrast"],e["grade.saturation"]);t("grade",""!==n,I(n));const a=this.map.styleLightDarkTheme;var i;t("fog",e["fog.intensity"]>0,{...I(C(e["fog.intensity"],a)),...L(f(e["fog.reach"])),backgroundImage:x(e["fog.intensity"],e["fog.reach"],a)}),t("edgeBlur",e["edgeBlur.intensity"]>0,{...I((i=e["edgeBlur.intensity"],`blur(${i}px) ${v}`)),...L(f(e["edgeBlur.reach"]))}),t("tint",e["tint.opacity"]>0,{backgroundColor:e["tint.color"],opacity:String(e["tint.opacity"])}),t("vignette",0!==e["vignette.intensity"],{backgroundImage:u(e["vignette.intensity"],e["vignette.reach"])});const s=e["bloom.intensity"]>0;t("bloom",s,{opacity:String(e["bloom.intensity"])}),s&&(this.warnIfBufferNotPreserved(),this.scheduleBloom())}scheduleBloom(){this.get("bloom.intensity")<=0||void 0!==this.bloomFrame||(this.bloomFrame=requestAnimationFrame(()=>{this.bloomFrame=void 0,this.drawBloom()}))}drawBloom(){const e=this.map.mapLibreMap.getCanvas(),t=Math.max(1,Math.round(.5*e.width)),n=Math.max(1,Math.round(.5*e.height));this.bloomCanvas.width===t&&this.bloomCanvas.height===n||(this.bloomCanvas.width=t,this.bloomCanvas.height=n);const a=this.bloomCanvas.getContext("2d");a&&(a.filter=g(this.get("bloom.radius"),this.get("bloom.threshold"),.5),a.clearRect(0,0,t,n),a.drawImage(e,0,0,t,n))}readBack(){const e=this.map.mapLibreMap;return new Promise(t=>{e.once("render",()=>{const n=e.getCanvas(),a=document.createElement("canvas");a.width=n.width,a.height=n.height;const i=a.getContext("2d");if(i){i.drawImage(n,0,0);const e=n.width/Math.max(1,n.clientWidth);S(i,n.width,n.height,e,E(this.settings),this.map.styleLightDarkTheme)}t(a)}),e.triggerRepaint()})}settled(e=15e3){const t=this.map.mapLibreMap;return new Promise(n=>{const a=()=>{clearTimeout(i),t.off("idle",a),n()},i=setTimeout(a,e);t.once("idle",a)})}warnIfBufferNotPreserved(){if(this.warnedBuffer)return;const e=this.map.mapLibreMap.getCanvas(),t=(e.getContext("webgl2")??e.getContext("webgl"))?.getContextAttributes?.();t&&!t.preserveDrawingBuffer&&(this.warnedBuffer=!0,console.warn("[MapEffects] bloom and capture read the map canvas, which needs `mapLibre: { canvasContextAttributes: { preserveDrawingBuffer: true } }` on the map's options."))}assertKnob(e){if(!(e in l))throw new Error(`Unknown effect knob '${e}'. Call describe() for the catalogue of knob ids.`)}validate(e,t){this.assertKnob(e);const{kind:n,range:a}=l[e];if("color"!==n){if("number"!=typeof t||!Number.isFinite(t))throw new RangeError(`Knob '${e}' expects a number; got ${String(t)}.`);if(a&&(t<a.min||t>a.max))throw new RangeError(`Knob '${e}' expects a number between ${a.min} and ${a.max}; got ${t}.`)}else if("string"!=typeof t||!t)throw new RangeError(`Knob '${e}' expects a CSS colour; got ${String(t)}.`)}};export{O as MapEffects,h as effectKnobIds};
2
+ //# sourceMappingURL=index.es.js.map