@versatiles/style 5.7.0 → 5.8.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 CHANGED
@@ -152,10 +152,10 @@ subgraph 1["color"]
152
152
  2["abstract.ts"]
153
153
  3["hsl.ts"]
154
154
  4["hsv.ts"]
155
- 5["rgb.ts"]
155
+ 5["random.ts"]
156
156
  6["utils.ts"]
157
- 7["index.ts"]
158
- 8["random.ts"]
157
+ 7["rgb.ts"]
158
+ 8["index.ts"]
159
159
  end
160
160
  subgraph 9["guess_style"]
161
161
  A["guess_style.ts"]
@@ -195,28 +195,29 @@ end
195
195
  end
196
196
  3-->2
197
197
  3-->4
198
- 3-->5
198
+ 3-->7
199
199
  3-->6
200
200
  4-->2
201
201
  4-->3
202
202
  4-->5
203
+ 4-->7
203
204
  4-->6
204
- 5-->2
205
- 5-->3
206
205
  5-->4
207
206
  5-->6
208
207
  7-->2
209
208
  7-->3
210
209
  7-->4
211
- 7-->5
210
+ 7-->6
211
+ 8-->2
212
+ 8-->3
212
213
  8-->4
213
- 8-->6
214
- A-->8
214
+ 8-->7
215
+ A-->5
215
216
  A-->C
216
217
  A-->E
217
218
  A-->W
218
219
  A-->X
219
- C-->7
220
+ C-->8
220
221
  E-->F
221
222
  E-->Q
222
223
  E-->R
@@ -224,7 +225,7 @@ E-->S
224
225
  E-->T
225
226
  E-->U
226
227
  F-->H
227
- H-->7
228
+ H-->8
228
229
  H-->C
229
230
  H-->J
230
231
  H-->M
@@ -232,10 +233,10 @@ H-->O
232
233
  H-->P
233
234
  J-->K
234
235
  J-->L
235
- M-->7
236
+ M-->8
236
237
  M-->C
237
238
  M-->N
238
- O-->7
239
+ O-->8
239
240
  Q-->F
240
241
  R-->F
241
242
  S-->F
@@ -244,7 +245,7 @@ U-->F
244
245
  W-->X
245
246
  W-->Y
246
247
  Z-->A
247
- 10-->7
248
+ 10-->8
248
249
  10-->Z
249
250
  10-->E
250
251
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  import { SpriteSpecification, StyleSpecification } from '@maplibre/maplibre-gl-style-spec';
2
2
  export { SpriteSpecification } from '@maplibre/maplibre-gl-style-spec';
3
3
 
4
+ interface RandomColorOptions {
5
+ seed?: string;
6
+ hue?: number | string;
7
+ opacity?: number;
8
+ luminosity?: number | string;
9
+ saturation?: number | string;
10
+ }
11
+
4
12
  /**
5
13
  * Represents an RGB color with optional alpha transparency.
6
14
  *
@@ -241,6 +249,7 @@ declare class HSV extends Color {
241
249
  * @returns A new HSV color with the updated hue component.
242
250
  */
243
251
  setHue(value: number): HSV;
252
+ static randomColor(options?: RandomColorOptions): HSV;
244
253
  }
245
254
 
246
255
  /**
@@ -751,4 +760,4 @@ declare const styles: {
751
760
  };
752
761
 
753
762
  export { Color, HSL, HSV, RGB, colorful, eclipse, graybeard, guessStyle, neutrino, shadow, styles };
754
- export type { GuessStyleOptions, Language, RecolorOptions, StyleBuilderColorKey, StyleBuilderColors, StyleBuilderFonts, StyleBuilderFunction, StyleBuilderOptions, TileJSONSpecification, TileJSONSpecificationRaster, TileJSONSpecificationVector, VectorLayer };
763
+ export type { GuessStyleOptions, Language, RandomColorOptions, RecolorOptions, StyleBuilderColorKey, StyleBuilderColors, StyleBuilderFonts, StyleBuilderFunction, StyleBuilderOptions, TileJSONSpecification, TileJSONSpecificationRaster, TileJSONSpecificationVector, VectorLayer };
package/dist/index.js CHANGED
@@ -153,6 +153,136 @@ function formatFloat(num, precision) {
153
153
  return num.toFixed(precision).replace(/0+$/, '').replace(/\.$/, '');
154
154
  }
155
155
 
156
+ let colorDictionary = new Map();
157
+ function randomColor(options) {
158
+ if (colorDictionary.size === 0)
159
+ colorDictionary = initColorDictionary();
160
+ options ??= {};
161
+ let seed = inputToSeed(options.seed);
162
+ const H = pickHue(options);
163
+ const S = pickSaturation(H, options);
164
+ const V = pickBrightness(H, S, options);
165
+ return new HSV(H, S, V, options.opacity ?? 1);
166
+ function pickHue(options) {
167
+ return mod(randomWithin(getHueRange(options.hue)), 360);
168
+ function getHueRange(hue) {
169
+ if (typeof hue === 'number') {
170
+ hue = mod(hue, 360);
171
+ return [hue, hue];
172
+ }
173
+ if (typeof hue === 'string') {
174
+ const color = colorDictionary.get(hue);
175
+ if (color?.hueRange)
176
+ return color.hueRange;
177
+ }
178
+ return [0, 360];
179
+ }
180
+ }
181
+ function pickSaturation(hue, options) {
182
+ if (options.hue === 'monochrome')
183
+ return 0;
184
+ if (options.luminosity === 'random')
185
+ return randomWithin([0, 100]);
186
+ let [sMin, sMax] = getColorInfo(hue).saturationRange;
187
+ if (options.saturation === 'strong')
188
+ return sMax;
189
+ switch (options.luminosity) {
190
+ case 'bright':
191
+ sMin = 55;
192
+ break;
193
+ case 'dark':
194
+ sMin = sMax - 10;
195
+ break;
196
+ case 'light':
197
+ sMax = 55;
198
+ break;
199
+ }
200
+ return randomWithin([sMin, sMax]);
201
+ }
202
+ function pickBrightness(h, s, options) {
203
+ let bMin = getMinimumBrightness(h, s), bMax = 100;
204
+ if (typeof options.luminosity === 'number') {
205
+ bMin = options.luminosity;
206
+ bMax = options.luminosity;
207
+ }
208
+ else {
209
+ switch (options.luminosity) {
210
+ case 'dark':
211
+ bMax = Math.min(100, bMin + 20);
212
+ break;
213
+ case 'light':
214
+ bMin = (bMax + bMin) / 2;
215
+ break;
216
+ case 'random':
217
+ bMin = 0;
218
+ bMax = 100;
219
+ break;
220
+ }
221
+ }
222
+ return randomWithin([bMin, bMax]);
223
+ function getMinimumBrightness(h, s) {
224
+ const { lowerBounds } = getColorInfo(h);
225
+ for (let i = 0; i < lowerBounds.length - 1; i++) {
226
+ const [s1, v1] = lowerBounds[i];
227
+ const [s2, v2] = lowerBounds[i + 1];
228
+ if (s >= s1 && s <= s2) {
229
+ const m = (v2 - v1) / (s2 - s1), b = v1 - m * s1;
230
+ return m * s + b;
231
+ }
232
+ }
233
+ return 0;
234
+ }
235
+ }
236
+ function randomWithin(range) {
237
+ //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
238
+ seed = (seed * 9301 + 49297) % 233280;
239
+ return Math.floor(range[0] + seed / 233280.0 * (range[1] - range[0]));
240
+ }
241
+ }
242
+ function inputToSeed(input) {
243
+ if (input == null)
244
+ return 0;
245
+ if (typeof input === 'number')
246
+ return input;
247
+ let i = 0;
248
+ for (let p = 0; p < input.length; p++)
249
+ i = (i * 0x101 + input.charCodeAt(p)) % 0x100000000;
250
+ return i;
251
+ }
252
+ function initColorDictionary() {
253
+ const dict = new Map();
254
+ const defineColor = (name, hueRange, lowerBounds) => {
255
+ const [greyest] = lowerBounds;
256
+ const colorful = lowerBounds[lowerBounds.length - 1];
257
+ dict.set(name, {
258
+ hueRange,
259
+ lowerBounds,
260
+ saturationRange: [greyest[0], colorful[0]],
261
+ brightnessRange: [colorful[1], greyest[1]],
262
+ });
263
+ };
264
+ defineColor('monochrome', null, [[0, 0], [100, 0]]);
265
+ defineColor('red', [-26, 18], [[20, 100], [30, 92], [40, 89], [50, 85], [60, 78], [70, 70], [80, 60], [90, 55], [100, 50]]);
266
+ defineColor('orange', [18, 46], [[20, 100], [30, 93], [40, 88], [50, 86], [60, 85], [70, 70], [100, 70]]);
267
+ defineColor('yellow', [46, 62], [[25, 100], [40, 94], [50, 89], [60, 86], [70, 84], [80, 82], [90, 80], [100, 75]]);
268
+ defineColor('green', [62, 178], [[30, 100], [40, 90], [50, 85], [60, 81], [70, 74], [80, 64], [90, 50], [100, 40]]);
269
+ defineColor('blue', [178, 257], [[20, 100], [30, 86], [40, 80], [50, 74], [60, 60], [70, 52], [80, 44], [90, 39], [100, 35]]);
270
+ defineColor('purple', [257, 282], [[20, 100], [30, 87], [40, 79], [50, 70], [60, 65], [70, 59], [80, 52], [90, 45], [100, 42]]);
271
+ defineColor('pink', [282, 334], [[20, 100], [30, 90], [40, 86], [60, 84], [80, 80], [90, 75], [100, 73]]);
272
+ return dict;
273
+ }
274
+ function getColorInfo(hue) {
275
+ hue = mod(hue, 360);
276
+ if (hue >= 334)
277
+ hue -= 360;
278
+ for (const color of colorDictionary.values()) {
279
+ if (color.hueRange && hue >= color.hueRange[0] && hue <= color.hueRange[1]) {
280
+ return color;
281
+ }
282
+ }
283
+ throw Error('Color hue value not found');
284
+ }
285
+
156
286
  /**
157
287
  * Represents an RGB color with optional alpha transparency.
158
288
  *
@@ -639,6 +769,9 @@ class HSV extends Color {
639
769
  setHue(value) {
640
770
  return new HSV(value, this.s, this.v, this.a);
641
771
  }
772
+ static randomColor(options) {
773
+ return randomColor(options);
774
+ }
642
775
  }
643
776
 
644
777
  /**
@@ -1859,11 +1992,9 @@ function deepClone(obj) {
1859
1992
  }
1860
1993
  }
1861
1994
  if (isSimpleObject(obj)) {
1862
- // @ts-expect-error: Too complicated to handle
1863
1995
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, deepClone(value)]));
1864
1996
  }
1865
1997
  if (obj instanceof Array) {
1866
- // @ts-expect-error: Too complicated to handle
1867
1998
  return obj.map((e) => deepClone(e));
1868
1999
  }
1869
2000
  if (obj instanceof Color) {
@@ -1926,7 +2057,6 @@ function deepMerge(source0, ...sources) {
1926
2057
  continue;
1927
2058
  }
1928
2059
  if (sourceValue instanceof Color) {
1929
- // @ts-expect-error: Too complicated to handle
1930
2060
  target[key] = sourceValue.clone();
1931
2061
  continue;
1932
2062
  }
@@ -2198,6 +2328,7 @@ class StyleBuilder {
2198
2328
  #sourceName = 'versatiles-shortbread';
2199
2329
  build(options) {
2200
2330
  options ??= {};
2331
+ // @ts-expect-error globalThis may be undefined in some environments
2201
2332
  const baseUrl = options.baseUrl ?? globalThis?.document?.location?.origin ?? 'https://tiles.versatiles.org';
2202
2333
  const glyphs = options.glyphs ?? '/assets/glyphs/{fontstack}/{range}.pbf';
2203
2334
  const sprite = options.sprite ?? [{ id: 'basics', url: '/assets/sprites/basics/sprites' }];
@@ -3817,136 +3948,6 @@ function isRasterTileJSONSpecification(spec) {
3817
3948
  return true;
3818
3949
  }
3819
3950
 
3820
- let colorDictionary = new Map();
3821
- function randomColor(options) {
3822
- if (colorDictionary.size === 0)
3823
- colorDictionary = initColorDictionary();
3824
- options ??= {};
3825
- let seed = inputToSeed(options.seed);
3826
- const H = pickHue(options);
3827
- const S = pickSaturation(H, options);
3828
- const V = pickBrightness(H, S, options);
3829
- return new HSV(H, S, V, options.opacity ?? 1);
3830
- function pickHue(options) {
3831
- return mod(randomWithin(getHueRange(options.hue)), 360);
3832
- function getHueRange(hue) {
3833
- if (typeof hue === 'number') {
3834
- hue = mod(hue, 360);
3835
- return [hue, hue];
3836
- }
3837
- if (typeof hue === 'string') {
3838
- const color = colorDictionary.get(hue);
3839
- if (color?.hueRange)
3840
- return color.hueRange;
3841
- }
3842
- return [0, 360];
3843
- }
3844
- }
3845
- function pickSaturation(hue, options) {
3846
- if (options.hue === 'monochrome')
3847
- return 0;
3848
- if (options.luminosity === 'random')
3849
- return randomWithin([0, 100]);
3850
- let [sMin, sMax] = getColorInfo(hue).saturationRange;
3851
- if (options.saturation === 'strong')
3852
- return sMax;
3853
- switch (options.luminosity) {
3854
- case 'bright':
3855
- sMin = 55;
3856
- break;
3857
- case 'dark':
3858
- sMin = sMax - 10;
3859
- break;
3860
- case 'light':
3861
- sMax = 55;
3862
- break;
3863
- }
3864
- return randomWithin([sMin, sMax]);
3865
- }
3866
- function pickBrightness(h, s, options) {
3867
- let bMin = getMinimumBrightness(h, s), bMax = 100;
3868
- if (typeof options.luminosity === 'number') {
3869
- bMin = options.luminosity;
3870
- bMax = options.luminosity;
3871
- }
3872
- else {
3873
- switch (options.luminosity) {
3874
- case 'dark':
3875
- bMax = Math.min(100, bMin + 20);
3876
- break;
3877
- case 'light':
3878
- bMin = (bMax + bMin) / 2;
3879
- break;
3880
- case 'random':
3881
- bMin = 0;
3882
- bMax = 100;
3883
- break;
3884
- }
3885
- }
3886
- return randomWithin([bMin, bMax]);
3887
- function getMinimumBrightness(h, s) {
3888
- const { lowerBounds } = getColorInfo(h);
3889
- for (let i = 0; i < lowerBounds.length - 1; i++) {
3890
- const [s1, v1] = lowerBounds[i];
3891
- const [s2, v2] = lowerBounds[i + 1];
3892
- if (s >= s1 && s <= s2) {
3893
- const m = (v2 - v1) / (s2 - s1), b = v1 - m * s1;
3894
- return m * s + b;
3895
- }
3896
- }
3897
- return 0;
3898
- }
3899
- }
3900
- function randomWithin(range) {
3901
- //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
3902
- seed = (seed * 9301 + 49297) % 233280;
3903
- return Math.floor(range[0] + seed / 233280.0 * (range[1] - range[0]));
3904
- }
3905
- }
3906
- function inputToSeed(input) {
3907
- if (input == null)
3908
- return 0;
3909
- if (typeof input === 'number')
3910
- return input;
3911
- let i = 0;
3912
- for (let p = 0; p < input.length; p++)
3913
- i = (i * 0x101 + input.charCodeAt(p)) % 0x100000000;
3914
- return i;
3915
- }
3916
- function initColorDictionary() {
3917
- const dict = new Map();
3918
- const defineColor = (name, hueRange, lowerBounds) => {
3919
- const [greyest] = lowerBounds;
3920
- const colorful = lowerBounds[lowerBounds.length - 1];
3921
- dict.set(name, {
3922
- hueRange,
3923
- lowerBounds,
3924
- saturationRange: [greyest[0], colorful[0]],
3925
- brightnessRange: [colorful[1], greyest[1]],
3926
- });
3927
- };
3928
- defineColor('monochrome', null, [[0, 0], [100, 0]]);
3929
- defineColor('red', [-26, 18], [[20, 100], [30, 92], [40, 89], [50, 85], [60, 78], [70, 70], [80, 60], [90, 55], [100, 50]]);
3930
- defineColor('orange', [18, 46], [[20, 100], [30, 93], [40, 88], [50, 86], [60, 85], [70, 70], [100, 70]]);
3931
- defineColor('yellow', [46, 62], [[25, 100], [40, 94], [50, 89], [60, 86], [70, 84], [80, 82], [90, 80], [100, 75]]);
3932
- defineColor('green', [62, 178], [[30, 100], [40, 90], [50, 85], [60, 81], [70, 74], [80, 64], [90, 50], [100, 40]]);
3933
- defineColor('blue', [178, 257], [[20, 100], [30, 86], [40, 80], [50, 74], [60, 60], [70, 52], [80, 44], [90, 39], [100, 35]]);
3934
- defineColor('purple', [257, 282], [[20, 100], [30, 87], [40, 79], [50, 70], [60, 65], [70, 59], [80, 52], [90, 45], [100, 42]]);
3935
- defineColor('pink', [282, 334], [[20, 100], [30, 90], [40, 86], [60, 84], [80, 80], [90, 75], [100, 73]]);
3936
- return dict;
3937
- }
3938
- function getColorInfo(hue) {
3939
- hue = mod(hue, 360);
3940
- if (hue >= 334)
3941
- hue -= 360;
3942
- for (const color of colorDictionary.values()) {
3943
- if (color.hueRange && hue >= color.hueRange[0] && hue <= color.hueRange[1]) {
3944
- return color;
3945
- }
3946
- }
3947
- throw Error('Color hue value not found');
3948
- }
3949
-
3950
3951
  /**
3951
3952
  * Generates a style specification based on the provided TileJSON specification and optional parameters.
3952
3953
  *
@@ -4129,7 +4130,7 @@ function sourceFromSpec(spec, type) {
4129
4130
  * <body>
4130
4131
  * <!-- ... -->
4131
4132
  * <script>
4132
- * const style = VersatilesStyle.colorful();
4133
+ * const style = VersaTilesStyle.colorful();
4133
4134
  * // ...
4134
4135
  * </script>
4135
4136
  * </body>
@@ -4141,8 +4142,8 @@ function sourceFromSpec(spec, type) {
4141
4142
  * npm i @versatiles/style
4142
4143
  * ```
4143
4144
  * ```
4144
- * import { colorful } from 'versatiles-style';
4145
- * // OR: const { colorful } = require('versatiles-style');
4145
+ * import { colorful } from '@versatiles/style';
4146
+ * // OR: const { colorful } = require('@versatiles/style');
4146
4147
  * const style = colorful();
4147
4148
  * ```
4148
4149
  *