@versatiles/style 5.5.2 → 5.7.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 +36 -33
- package/dist/index.d.ts +539 -65
- package/dist/index.js +782 -217
- package/dist/index.js.map +1 -1
- package/package.json +26 -25
- package/src/color/abstract.ts +145 -26
- package/src/color/hsl.ts +88 -5
- package/src/color/hsv.ts +73 -5
- package/src/color/index.test.ts +0 -20
- package/src/color/index.ts +0 -3
- package/src/color/random.test.ts +21 -0
- package/src/color/rgb.test.ts +40 -72
- package/src/color/rgb.ts +152 -7
- package/src/color/utils.ts +10 -4
- package/src/guess_style/guess_style.test.ts +1 -1
- package/src/guess_style/guess_style.ts +42 -2
- package/src/index.test.ts +2 -1
- package/src/index.ts +89 -4
- package/src/shortbread/layers.ts +30 -5
- package/src/style_builder/recolor.test.ts +46 -0
- package/src/style_builder/recolor.ts +161 -34
- package/src/style_builder/style_builder.test.ts +2 -0
- package/src/style_builder/style_builder.ts +8 -9
- package/src/style_builder/types.ts +23 -58
- package/src/styles/colorful.ts +36 -7
- package/src/styles/index.ts +2 -0
- package/src/styles/shadow.ts +11 -0
package/src/color/rgb.test.ts
CHANGED
|
@@ -134,94 +134,62 @@ describe('RGB Class', () => {
|
|
|
134
134
|
return cb(new RGB(50, 150, 200, 0.8)).round().asArray();
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
test('clamps extreme gamma values', () => {
|
|
143
|
-
expect(pc(c => c.gamma(0.001))).toStrictEqual([255, 255, 255, 0.8]);
|
|
144
|
-
expect(pc(c => c.gamma(1000))).toStrictEqual([0, 0, 0, 0.8]);
|
|
145
|
-
});
|
|
137
|
+
test('adjusts gamma correctly', () => {
|
|
138
|
+
expect(pc(c => c.gamma(2.2))).toStrictEqual([7, 79, 149, 0.8]);
|
|
139
|
+
expect(pc(c => c.gamma(0.001))).toStrictEqual([255, 255, 255, 0.8]);
|
|
140
|
+
expect(pc(c => c.gamma(1000))).toStrictEqual([0, 0, 0, 0.8]);
|
|
146
141
|
});
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
expect(pc(c => c.invert())).toStrictEqual([205, 105, 55, 0.8]);
|
|
151
|
-
});
|
|
143
|
+
test('inverts RGB values correctly', () => {
|
|
144
|
+
expect(pc(c => c.invert())).toStrictEqual([205, 105, 55, 0.8]);
|
|
152
145
|
});
|
|
153
146
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
test('clamps extreme contrast values', () => {
|
|
160
|
-
expect(pc(c => c.contrast(1e6))).toStrictEqual([0, 255, 255, 0.8]);
|
|
161
|
-
expect(pc(c => c.contrast(0))).toStrictEqual([128, 128, 128, 0.8]);
|
|
162
|
-
});
|
|
147
|
+
test('adjusts contrast correctly', () => {
|
|
148
|
+
expect(pc(c => c.contrast(1.5))).toStrictEqual([11, 161, 236, 0.8]);
|
|
149
|
+
expect(pc(c => c.contrast(1e6))).toStrictEqual([0, 255, 255, 0.8]);
|
|
150
|
+
expect(pc(c => c.contrast(0))).toStrictEqual([128, 128, 128, 0.8]);
|
|
163
151
|
});
|
|
164
152
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
test('decreases brightness correctly', () => {
|
|
171
|
-
expect(pc(c => c.brightness(-0.5))).toStrictEqual([25, 75, 100, 0.8]);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
test('clamps brightness values', () => {
|
|
175
|
-
expect(pc(c => c.brightness(2))).toStrictEqual([255, 255, 255, 0.8]);
|
|
176
|
-
expect(pc(c => c.brightness(-2))).toStrictEqual([0, 0, 0, 0.8]);
|
|
177
|
-
});
|
|
153
|
+
test('increases brightness correctly', () => {
|
|
154
|
+
expect(pc(c => c.brightness(0.5))).toStrictEqual([153, 203, 228, 0.8]);
|
|
155
|
+
expect(pc(c => c.brightness(-0.5))).toStrictEqual([25, 75, 100, 0.8]);
|
|
156
|
+
expect(pc(c => c.brightness(2))).toStrictEqual([255, 255, 255, 0.8]);
|
|
157
|
+
expect(pc(c => c.brightness(-2))).toStrictEqual([0, 0, 0, 0.8]);
|
|
178
158
|
});
|
|
179
159
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
test('handles extreme tint values', () => {
|
|
187
|
-
const tintColor = new RGB(255, 0, 0);
|
|
188
|
-
expect(pc(c => c.tint(1, tintColor))).toStrictEqual([200, 50, 50, 0.8]);
|
|
189
|
-
expect(pc(c => c.tint(0, tintColor))).toStrictEqual([50, 150, 200, 0.8]);
|
|
190
|
-
});
|
|
160
|
+
test('tints color correctly', () => {
|
|
161
|
+
const tintColor = new RGB(255, 0, 0);
|
|
162
|
+
expect(pc(c => c.tint(0.5, tintColor))).toStrictEqual([125, 100, 125, 0.8]);
|
|
163
|
+
expect(pc(c => c.tint(1, tintColor))).toStrictEqual([200, 50, 50, 0.8]);
|
|
164
|
+
expect(pc(c => c.tint(0, tintColor))).toStrictEqual([50, 150, 200, 0.8]);
|
|
191
165
|
});
|
|
192
166
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
});
|
|
167
|
+
test('blends color correctly', () => {
|
|
168
|
+
const blendColor = new RGB(255, 0, 0);
|
|
169
|
+
expect(pc(c => c.blend(0.2, blendColor))).toStrictEqual([91, 120, 160, 0.8]);
|
|
170
|
+
expect(pc(c => c.blend(0.5, blendColor))).toStrictEqual([153, 75, 100, 0.8]);
|
|
171
|
+
expect(pc(c => c.blend(0.8, blendColor))).toStrictEqual([214, 30, 40, 0.8]);
|
|
172
|
+
expect(pc(c => c.blend(1, blendColor))).toStrictEqual([255, 0, 0, 0.8]);
|
|
173
|
+
expect(pc(c => c.blend(0, blendColor))).toStrictEqual([50, 150, 200, 0.8]);
|
|
201
174
|
});
|
|
202
175
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
test('clamps darken ratio', () => {
|
|
209
|
-
expect(pc(c => c.darken(1))).toStrictEqual([0, 0, 0, 0.8]);
|
|
210
|
-
expect(pc(c => c.darken(2))).toStrictEqual([0, 0, 0, 0.8]);
|
|
211
|
-
});
|
|
176
|
+
test('lightens the color correctly', () => {
|
|
177
|
+
expect(pc(c => c.lighten(0.5))).toStrictEqual([153, 203, 228, 0.8]);
|
|
178
|
+
expect(pc(c => c.lighten(2))).toStrictEqual([255, 255, 255, 0.8]);
|
|
212
179
|
});
|
|
213
180
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
181
|
+
test('darkens the color correctly', () => {
|
|
182
|
+
expect(pc(c => c.darken(0.5))).toStrictEqual([25, 75, 100, 0.8]);
|
|
183
|
+
expect(pc(c => c.darken(1))).toStrictEqual([0, 0, 0, 0.8]);
|
|
184
|
+
expect(pc(c => c.darken(2))).toStrictEqual([0, 0, 0, 0.8]);
|
|
185
|
+
});
|
|
218
186
|
|
|
219
|
-
|
|
220
|
-
|
|
187
|
+
test('fades color correctly', () => {
|
|
188
|
+
expect(pc(c => c.fade(0.5))).toStrictEqual([50, 150, 200, 0.4]);
|
|
189
|
+
expect(pc(c => c.fade(1))).toStrictEqual([50, 150, 200, 0]);
|
|
221
190
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
191
|
+
const fullyOpaque = new RGB(50, 150, 200, 1);
|
|
192
|
+
expect(fullyOpaque.fade(0).asArray()).toStrictEqual([50, 150, 200, 1]);
|
|
225
193
|
});
|
|
226
194
|
});
|
|
227
195
|
});
|
package/src/color/rgb.ts
CHANGED
|
@@ -3,12 +3,40 @@ import { HSV } from './hsv.js';
|
|
|
3
3
|
import { Color } from './abstract.js';
|
|
4
4
|
import { clamp, formatFloat } from './utils.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Represents an RGB color with optional alpha transparency.
|
|
8
|
+
*
|
|
9
|
+
* @extends Color
|
|
10
|
+
*/
|
|
6
11
|
export class RGB extends Color {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
readonly
|
|
11
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Red component (0-255).
|
|
14
|
+
*/
|
|
15
|
+
readonly r;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Green component (0-255).
|
|
19
|
+
*/
|
|
20
|
+
readonly g;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Blue component (0-255).
|
|
24
|
+
*/
|
|
25
|
+
readonly b;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Alpha component (0-1).
|
|
29
|
+
*/
|
|
30
|
+
readonly a;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Creates an instance of RGB.
|
|
34
|
+
*
|
|
35
|
+
* @param r - Red component (0-255).
|
|
36
|
+
* @param g - Green component (0-255).
|
|
37
|
+
* @param b - Blue component (0-255).
|
|
38
|
+
* @param a - Alpha component (0-1), defaults to 1.
|
|
39
|
+
*/
|
|
12
40
|
constructor(r: number, g: number, b: number, a: number = 1) {
|
|
13
41
|
super();
|
|
14
42
|
this.r = clamp(r, 0, 255);
|
|
@@ -17,14 +45,29 @@ export class RGB extends Color {
|
|
|
17
45
|
this.a = clamp(a, 0, 1);
|
|
18
46
|
}
|
|
19
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Creates a clone of the current RGB color.
|
|
50
|
+
*
|
|
51
|
+
* @returns A new RGB instance with the same color values.
|
|
52
|
+
*/
|
|
20
53
|
clone(): RGB {
|
|
21
54
|
return new RGB(this.r, this.g, this.b, this.a);
|
|
22
55
|
}
|
|
23
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Returns the RGB color as an array.
|
|
59
|
+
*
|
|
60
|
+
* @returns An array containing the red, green, blue, and alpha components.
|
|
61
|
+
*/
|
|
24
62
|
asArray(): [number, number, number, number] {
|
|
25
63
|
return [this.r, this.g, this.b, this.a];
|
|
26
64
|
}
|
|
27
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Rounds the RGB color components to the nearest integer.
|
|
68
|
+
*
|
|
69
|
+
* @returns A new RGB instance with rounded color values.
|
|
70
|
+
*/
|
|
28
71
|
round(): RGB {
|
|
29
72
|
return new RGB(
|
|
30
73
|
Math.round(this.r),
|
|
@@ -34,6 +77,11 @@ export class RGB extends Color {
|
|
|
34
77
|
);
|
|
35
78
|
}
|
|
36
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Returns the RGB color as a string.
|
|
82
|
+
*
|
|
83
|
+
* @returns A string representation of the RGB color in either `rgb` or `rgba` format.
|
|
84
|
+
*/
|
|
37
85
|
asString(): string {
|
|
38
86
|
if (this.a === 1) {
|
|
39
87
|
return `rgb(${this.r.toFixed(0)},${this.g.toFixed(0)},${this.b.toFixed(0)})`;
|
|
@@ -42,6 +90,11 @@ export class RGB extends Color {
|
|
|
42
90
|
}
|
|
43
91
|
}
|
|
44
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Returns the RGB color as a hexadecimal string.
|
|
95
|
+
*
|
|
96
|
+
* @returns A string representation of the RGB color in hexadecimal format.
|
|
97
|
+
*/
|
|
45
98
|
asHex(): string {
|
|
46
99
|
const r = Math.round(this.r).toString(16).padStart(2, '0');
|
|
47
100
|
const g = Math.round(this.g).toString(16).padStart(2, '0');
|
|
@@ -55,6 +108,11 @@ export class RGB extends Color {
|
|
|
55
108
|
}
|
|
56
109
|
}
|
|
57
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Converts the RGB color to an HSL color.
|
|
113
|
+
*
|
|
114
|
+
* @returns An HSL instance representing the same color.
|
|
115
|
+
*/
|
|
58
116
|
asHSL(): HSL {
|
|
59
117
|
const r = this.r / 255;
|
|
60
118
|
const g = this.g / 255;
|
|
@@ -82,6 +140,11 @@ export class RGB extends Color {
|
|
|
82
140
|
return new HSL(h, s * 100, l * 100, this.a);
|
|
83
141
|
};
|
|
84
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Converts the RGB color to an HSV color.
|
|
145
|
+
*
|
|
146
|
+
* @returns An HSV instance representing the same color.
|
|
147
|
+
*/
|
|
85
148
|
asHSV(): HSV {
|
|
86
149
|
const r = this.r / 255;
|
|
87
150
|
const g = this.g / 255;
|
|
@@ -112,14 +175,31 @@ export class RGB extends Color {
|
|
|
112
175
|
return new HSV(h * 360, s * 100, v * 100, this.a);
|
|
113
176
|
}
|
|
114
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Returns the RGB color.
|
|
180
|
+
*
|
|
181
|
+
* @returns The current RGB instance.
|
|
182
|
+
*/
|
|
115
183
|
asRGB(): RGB {
|
|
116
184
|
return this.clone();
|
|
117
185
|
}
|
|
118
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Returns the RGB color.
|
|
189
|
+
*
|
|
190
|
+
* @returns The current RGB instance.
|
|
191
|
+
*/
|
|
119
192
|
toRGB(): RGB {
|
|
120
193
|
return this;
|
|
121
194
|
}
|
|
122
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Parses a string or Color instance into an RGB color.
|
|
198
|
+
*
|
|
199
|
+
* @param input - The input string or Color instance to parse.
|
|
200
|
+
* @returns A new RGB instance representing the parsed color.
|
|
201
|
+
* @throws Will throw an error if the input string is not a valid RGB color string.
|
|
202
|
+
*/
|
|
123
203
|
static parse(input: string | Color): RGB {
|
|
124
204
|
if (input instanceof Color) return input.asRGB();
|
|
125
205
|
|
|
@@ -167,7 +247,12 @@ export class RGB extends Color {
|
|
|
167
247
|
throw new Error(`Invalid RGB color string: "${input}"`);
|
|
168
248
|
}
|
|
169
249
|
|
|
170
|
-
|
|
250
|
+
/**
|
|
251
|
+
* Adjusts the gamma of the RGB color.
|
|
252
|
+
*
|
|
253
|
+
* @param value - The gamma value to apply.
|
|
254
|
+
* @returns A new RGB instance with the adjusted gamma.
|
|
255
|
+
*/
|
|
171
256
|
gamma(value: number): RGB {
|
|
172
257
|
if (value < 1e-3) value = 1e-3;
|
|
173
258
|
if (value > 1e3) value = 1e3;
|
|
@@ -179,6 +264,11 @@ export class RGB extends Color {
|
|
|
179
264
|
);
|
|
180
265
|
}
|
|
181
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Inverts the RGB color.
|
|
269
|
+
*
|
|
270
|
+
* @returns A new RGB instance with the inverted color values.
|
|
271
|
+
*/
|
|
182
272
|
invert(): RGB {
|
|
183
273
|
return new RGB(
|
|
184
274
|
255 - this.r,
|
|
@@ -188,6 +278,12 @@ export class RGB extends Color {
|
|
|
188
278
|
);
|
|
189
279
|
}
|
|
190
280
|
|
|
281
|
+
/**
|
|
282
|
+
* Adjusts the contrast of the RGB color.
|
|
283
|
+
*
|
|
284
|
+
* @param value - The contrast value to apply.
|
|
285
|
+
* @returns A new RGB instance with the adjusted contrast.
|
|
286
|
+
*/
|
|
191
287
|
contrast(value: number): RGB {
|
|
192
288
|
if (value < 0) value = 0;
|
|
193
289
|
if (value > 1e6) value = 1e6;
|
|
@@ -199,6 +295,12 @@ export class RGB extends Color {
|
|
|
199
295
|
);
|
|
200
296
|
}
|
|
201
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Adjusts the brightness of the RGB color.
|
|
300
|
+
*
|
|
301
|
+
* @param value - The brightness value to apply.
|
|
302
|
+
* @returns A new RGB instance with the adjusted brightness.
|
|
303
|
+
*/
|
|
202
304
|
brightness(value: number): RGB {
|
|
203
305
|
if (value < -1) value = -1;
|
|
204
306
|
if (value > 1) value = 1;
|
|
@@ -212,10 +314,17 @@ export class RGB extends Color {
|
|
|
212
314
|
);
|
|
213
315
|
}
|
|
214
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Tints the RGB color with another color.
|
|
319
|
+
*
|
|
320
|
+
* @param value - The tint value to apply.
|
|
321
|
+
* @param tintColor - The color to use for tinting.
|
|
322
|
+
* @returns A new RGB instance with the applied tint.
|
|
323
|
+
*/
|
|
215
324
|
tint(value: number, tintColor: Color): RGB {
|
|
216
325
|
if (value < 0) value = 0;
|
|
217
326
|
if (value > 1) value = 1;
|
|
218
|
-
const rgbNew = this.setHue(tintColor.
|
|
327
|
+
const rgbNew = this.setHue(tintColor.asHSV().h).asRGB();
|
|
219
328
|
return new RGB(
|
|
220
329
|
this.r * (1 - value) + value * rgbNew.r,
|
|
221
330
|
this.g * (1 - value) + value * rgbNew.g,
|
|
@@ -224,6 +333,30 @@ export class RGB extends Color {
|
|
|
224
333
|
)
|
|
225
334
|
}
|
|
226
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Blends the RGB color with another color.
|
|
338
|
+
*
|
|
339
|
+
* @param value - The blend value to apply.
|
|
340
|
+
* @param blendColor - The color to blend with.
|
|
341
|
+
* @returns A new RGB instance with the blended color.
|
|
342
|
+
*/
|
|
343
|
+
blend(value: number, blendColor: Color): RGB {
|
|
344
|
+
value = clamp(value ?? 0, 0, 1);
|
|
345
|
+
const rgbNew = blendColor.asRGB();
|
|
346
|
+
return new RGB(
|
|
347
|
+
this.r * (1 - value) + value * rgbNew.r,
|
|
348
|
+
this.g * (1 - value) + value * rgbNew.g,
|
|
349
|
+
this.b * (1 - value) + value * rgbNew.b,
|
|
350
|
+
this.a
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Lightens the RGB color.
|
|
356
|
+
*
|
|
357
|
+
* @param ratio - The ratio to lighten the color by.
|
|
358
|
+
* @returns A new RGB instance with the lightened color.
|
|
359
|
+
*/
|
|
227
360
|
lighten(ratio: number): RGB {
|
|
228
361
|
return new RGB(
|
|
229
362
|
clamp(255 - (255 - this.r) * (1 - ratio), 0, 255),
|
|
@@ -233,6 +366,12 @@ export class RGB extends Color {
|
|
|
233
366
|
);
|
|
234
367
|
}
|
|
235
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Darkens the RGB color.
|
|
371
|
+
*
|
|
372
|
+
* @param ratio - The ratio to darken the color by.
|
|
373
|
+
* @returns A new RGB instance with the darkened color.
|
|
374
|
+
*/
|
|
236
375
|
darken(ratio: number): RGB {
|
|
237
376
|
return new RGB(
|
|
238
377
|
clamp(this.r * (1 - ratio), 0, 255),
|
|
@@ -242,6 +381,12 @@ export class RGB extends Color {
|
|
|
242
381
|
);
|
|
243
382
|
}
|
|
244
383
|
|
|
384
|
+
/**
|
|
385
|
+
* Fades the RGB color by reducing its alpha value.
|
|
386
|
+
*
|
|
387
|
+
* @param value - The fade value to apply.
|
|
388
|
+
* @returns A new RGB instance with the faded color.
|
|
389
|
+
*/
|
|
245
390
|
fade(value: number): RGB {
|
|
246
391
|
return new RGB(this.r, this.g, this.b, this.a * (1 - value));
|
|
247
392
|
}
|
package/src/color/utils.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
export function clamp(
|
|
4
|
-
|
|
3
|
+
export function clamp(value: number, min: number, max: number): number {
|
|
4
|
+
if (value == null || isNaN(value)) return min;
|
|
5
|
+
if (value < min) return min;
|
|
6
|
+
if (value > max) return max;
|
|
7
|
+
return value;
|
|
5
8
|
}
|
|
6
9
|
|
|
7
|
-
export function mod(
|
|
8
|
-
|
|
10
|
+
export function mod(value: number, max: number): number {
|
|
11
|
+
value = value % max;
|
|
12
|
+
if (value < 0) value += max;
|
|
13
|
+
if (value == 0) return 0;
|
|
14
|
+
return value;
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
export function formatFloat(num: number, precision: number): string {
|
|
@@ -61,7 +61,7 @@ describe('guessStyle', () => {
|
|
|
61
61
|
it('should build shortbread vector styles', () => {
|
|
62
62
|
const style = guessStyle({ tiles, vector_layers: vectorLayersShortbread }, { baseUrl: 'http://example.com' });
|
|
63
63
|
|
|
64
|
-
expect(style.layers.length).toBe(
|
|
64
|
+
expect(style.layers.length).toBe(309);
|
|
65
65
|
style.layers = [];
|
|
66
66
|
|
|
67
67
|
expect(style).toStrictEqual({
|
|
@@ -3,15 +3,38 @@ import { isTileJSONSpecification } from '../types/index.js';
|
|
|
3
3
|
import { deepClone, resolveUrl } from '../lib/utils.js';
|
|
4
4
|
import type { BackgroundLayerSpecification, CircleLayerSpecification, FillLayerSpecification, LineLayerSpecification, RasterSourceSpecification, SourceSpecification, SpriteSpecification, StyleSpecification, VectorSourceSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
5
5
|
import { colorful } from '../styles/index.js';
|
|
6
|
-
import { Color } from '../color/index.js';
|
|
7
6
|
import { isRasterTileJSONSpecification } from '../types/tilejson.js';
|
|
7
|
+
import randomColor from '../color/random.js';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Options for guessing the style of a map.
|
|
11
|
+
*/
|
|
9
12
|
export interface GuessStyleOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Base URL to resolve URLs for tile sources, glyphs, and sprites.
|
|
15
|
+
*/
|
|
10
16
|
baseUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* URL template for glyphs.
|
|
19
|
+
*/
|
|
11
20
|
glyphs?: string;
|
|
21
|
+
/**
|
|
22
|
+
* URL template for sprites. See also {@link SpriteSpecification}.
|
|
23
|
+
*/
|
|
12
24
|
sprite?: SpriteSpecification;
|
|
13
25
|
}
|
|
14
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Generates a style specification based on the provided TileJSON specification and optional parameters.
|
|
29
|
+
*
|
|
30
|
+
* @param {TileJSONSpecification} tileJSON - The TileJSON specification to generate the style from.
|
|
31
|
+
* @param {GuessStyleOptions} [options] - Optional parameters to customize the style generation.
|
|
32
|
+
* @param {string} [options.baseUrl] - Base URL to resolve tile URLs.
|
|
33
|
+
* @param {string} [options.glyphs] - URL template for glyphs.
|
|
34
|
+
* @param {string} [options.sprite] - URL template for sprites.
|
|
35
|
+
* @returns {StyleSpecification} The generated style specification.
|
|
36
|
+
* @throws {Error} If the provided TileJSON specification is invalid.
|
|
37
|
+
*/
|
|
15
38
|
export function guessStyle(tileJSON: TileJSONSpecification, options?: GuessStyleOptions): StyleSpecification {
|
|
16
39
|
tileJSON = deepClone(tileJSON);
|
|
17
40
|
|
|
@@ -60,6 +83,23 @@ function getShortbreadStyle(spec: TileJSONSpecificationVector, builderOption: {
|
|
|
60
83
|
});
|
|
61
84
|
}
|
|
62
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Generates a Mapbox GL style specification based on the provided TileJSON vector specification.
|
|
88
|
+
*
|
|
89
|
+
* @param {TileJSONSpecificationVector} spec - The TileJSON vector specification containing vector layers.
|
|
90
|
+
* @returns {StyleSpecification} The generated Mapbox GL style specification.
|
|
91
|
+
*
|
|
92
|
+
* This function creates a style specification with background, circle, line, and fill layers.
|
|
93
|
+
* It assigns colors to the layers based on the vector layer IDs using predefined rules for hue, luminosity, and saturation.
|
|
94
|
+
*
|
|
95
|
+
* The resulting style specification includes:
|
|
96
|
+
* - A white background layer.
|
|
97
|
+
* - Circle layers for point features.
|
|
98
|
+
* - Line layers for line features.
|
|
99
|
+
* - Fill layers for polygon features.
|
|
100
|
+
*
|
|
101
|
+
* The source for the layers is created using the `sourceFromSpec` function with the provided vector specification.
|
|
102
|
+
*/
|
|
63
103
|
function getInspectorStyle(spec: TileJSONSpecificationVector): StyleSpecification {
|
|
64
104
|
const sourceName = 'vectorSource';
|
|
65
105
|
|
|
@@ -88,7 +128,7 @@ function getInspectorStyle(spec: TileJSONSpecificationVector): StyleSpecificatio
|
|
|
88
128
|
luminosity = 'light';
|
|
89
129
|
}
|
|
90
130
|
|
|
91
|
-
const color =
|
|
131
|
+
const color = randomColor({
|
|
92
132
|
hue,
|
|
93
133
|
luminosity,
|
|
94
134
|
saturation,
|
package/src/index.test.ts
CHANGED
|
@@ -3,13 +3,14 @@ import { VectorSourceSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
|
3
3
|
import type { VectorLayer } from './index.js';
|
|
4
4
|
import { guessStyle, styles } from './index.js';
|
|
5
5
|
|
|
6
|
-
const { colorful, eclipse, graybeard, neutrino } = styles;
|
|
6
|
+
const { colorful, eclipse, graybeard, neutrino, shadow } = styles;
|
|
7
7
|
|
|
8
8
|
describe('styles', () => {
|
|
9
9
|
[
|
|
10
10
|
{ name: 'colorful', builder: colorful },
|
|
11
11
|
{ name: 'eclipse', builder: eclipse },
|
|
12
12
|
{ name: 'graybeard', builder: graybeard },
|
|
13
|
+
{ name: 'shadow', builder: shadow },
|
|
13
14
|
{ name: 'neutrino', builder: neutrino },
|
|
14
15
|
].forEach(({ name, builder }) => {
|
|
15
16
|
it(`should create and test an instance of ${name}`, () => {
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* This library provides everything you need to build a map style.
|
|
3
|
+
*
|
|
4
|
+
* You can use it in the browser:
|
|
5
|
+
* ```html
|
|
6
|
+
* <html>
|
|
7
|
+
* <head>
|
|
8
|
+
* <script src="https://tiles.versatiles.org/assets/lib/versatiles-style/versatiles-style.js"></script>
|
|
9
|
+
* </head>
|
|
10
|
+
* <body>
|
|
11
|
+
* <!-- ... -->
|
|
12
|
+
* <script>
|
|
13
|
+
* const style = VersatilesStyle.colorful();
|
|
14
|
+
* // ...
|
|
15
|
+
* </script>
|
|
16
|
+
* </body>
|
|
17
|
+
* </html>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* or in Node.js:
|
|
21
|
+
* ```shell
|
|
22
|
+
* npm i @versatiles/style
|
|
23
|
+
* ```
|
|
24
|
+
* ```
|
|
25
|
+
* import { colorful } from 'versatiles-style';
|
|
26
|
+
* // OR: const { colorful } = require('versatiles-style');
|
|
27
|
+
* const style = colorful();
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* You probably want to use one of the following functions:
|
|
31
|
+
*
|
|
32
|
+
* ---
|
|
33
|
+
*
|
|
34
|
+
* ## Generate a style for OpenStreetMap data:
|
|
35
|
+
*
|
|
36
|
+
* To generate a style from scratch you can use on of the prepared style functions:
|
|
37
|
+
* - {@link colorful}
|
|
38
|
+
* - {@link eclipse}
|
|
39
|
+
* - {@link graybeard}
|
|
40
|
+
* - {@link neutrino}
|
|
41
|
+
* - {@link shadow}
|
|
42
|
+
*
|
|
43
|
+
* Each function accepts optional {@link StyleBuilderOptions} as argument to customize the style.
|
|
44
|
+
*
|
|
45
|
+
* Example:
|
|
46
|
+
* ```
|
|
47
|
+
* import { colorful } from 'versatiles-style';
|
|
48
|
+
* const style = colorful({
|
|
49
|
+
* baseUrl: 'https://tiles.example.org',
|
|
50
|
+
* recolor: {
|
|
51
|
+
* blend: 0.5,
|
|
52
|
+
* blendColor: '#FFF', // make all colors lighter
|
|
53
|
+
* }
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ---
|
|
58
|
+
*
|
|
59
|
+
* ## Guess a style based on a TileJSON:
|
|
60
|
+
*
|
|
61
|
+
* To guess a style from a TileJSON you can use {@link guessStyle}.
|
|
62
|
+
* This function needs a {@link TileJSONSpecification} and an optional {@link GuessStyleOptions} object.
|
|
63
|
+
* Example:
|
|
64
|
+
* ```
|
|
65
|
+
* import { guessStyle } from 'versatiles-style';
|
|
66
|
+
* const style = guessStyle(tilejson);
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ---
|
|
70
|
+
*
|
|
71
|
+
* ## Please help us to improve this library:
|
|
72
|
+
*
|
|
73
|
+
* This library is used in quite some projects of the VersaTiles ecosystem but it is still in an early stage.
|
|
74
|
+
* We are always looking for feedback, contributions, ideas, bug reports and help with the documentation.
|
|
75
|
+
*
|
|
76
|
+
* If you have any suggestions, please [open an issue](https://github.com/versatiles-org/versatiles-style/issues) or a pull request on [GitHub](https://github.com/versatiles-org/versatiles-style).
|
|
77
|
+
*
|
|
78
|
+
* If you want to know more about the VersaTiles project, please visit [versatiles.org](https://versatiles.org).
|
|
79
|
+
*
|
|
80
|
+
* @module
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
export { colorful, eclipse, graybeard, neutrino, shadow, type StyleBuilderFunction } from './styles/index.js';
|
|
84
|
+
import { colorful, eclipse, graybeard, neutrino, shadow } from './styles/index.js';
|
|
3
85
|
export const styles = {
|
|
4
86
|
colorful,
|
|
5
87
|
eclipse,
|
|
6
88
|
graybeard,
|
|
89
|
+
shadow,
|
|
7
90
|
neutrino,
|
|
8
91
|
};
|
|
9
92
|
|
|
10
93
|
export type { GuessStyleOptions } from './guess_style/index.js';
|
|
11
|
-
export type { RGB, HSL, HSV
|
|
94
|
+
export type { RGB, HSL, HSV } from './color/index.js';
|
|
12
95
|
export type { TileJSONSpecification, TileJSONSpecificationRaster, TileJSONSpecificationVector } from './types/tilejson.js';
|
|
13
96
|
export type { VectorLayer } from './types/index.js';
|
|
14
|
-
export type { StyleBuilderOptions, Language, StyleBuilderColors,
|
|
97
|
+
export type { StyleBuilderOptions, Language, StyleBuilderColors, StyleBuilderColorKey, StyleBuilderFonts } from './style_builder/types.js';
|
|
15
98
|
export type { RecolorOptions } from './style_builder/recolor.js';
|
|
16
99
|
|
|
17
100
|
export { guessStyle } from './guess_style/index.js';
|
|
18
101
|
export { Color } from './color/index.js';
|
|
102
|
+
|
|
103
|
+
export type { SpriteSpecification } from '@maplibre/maplibre-gl-style-spec';
|