@unmap/themes 0.8.0 → 0.9.1
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/dist/index.d.ts +16 -1
- package/dist/index.js +85 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -850,4 +850,19 @@ declare const THEME_PRESETS: ThemePreset[];
|
|
|
850
850
|
*/
|
|
851
851
|
declare function shuffleSeeds(rng?: () => number): Required<ThemeSeeds>;
|
|
852
852
|
|
|
853
|
-
|
|
853
|
+
/**
|
|
854
|
+
* Map an extracted image palette onto the four simple-mode seeds. Deterministic: the same
|
|
855
|
+
* colours always produce the same seeds, and `generateTheme` then carries the contrast
|
|
856
|
+
* guarantee. Lightness on land/water/nature is display-only (the generator re-hues stock
|
|
857
|
+
* ladders); accent is used verbatim for the marker and route.
|
|
858
|
+
*/
|
|
859
|
+
interface PaletteColor {
|
|
860
|
+
hex: string;
|
|
861
|
+
proportion: number;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Brand colours in, the four simple-mode seeds out. Empty input falls back to the stock seeds.
|
|
865
|
+
*/
|
|
866
|
+
declare function seedsFromPalette(colors: PaletteColor[]): Required<ThemeSeeds>;
|
|
867
|
+
|
|
868
|
+
export { BUILDINGS_3D_LAYER_ID, type BasemapOverrides, type ContrastWarning, DEFAULT_LAYER_VISIBILITY, DEFAULT_MARKER, DEFAULT_ROUTE, DEFAULT_SEEDS, type DeepPartial, LABEL_PAIRS, LAYER_GROUPS, type LabelRamp, type LayerGroup, MAX_CODE_LENGTH, MODES, type MarkerTheme, type Oklch, PRESET_CODE_PREFIX, PRESET_CODE_RE, type PaletteColor, RECIPES, type RampSet, type Recipe, type ResolvedTheme, type RoadRamp, type RouteTheme, STOCK_RAMPS, STYLE_THEMES, THEME_BASES, THEME_CODE_PREFIX, THEME_PRESETS, type ThemeBase, type ThemeDoc, ThemeError, type ThemeHalf, type ThemeLayers, type ThemeMode, type ThemePreset, type ThemeSeeds, amber, applyThemeLayers, aqua, azure, buildRecipes, cobalt, contrast, contrastWarnings, coral, decodePreset, decodeTheme, effectiveLayerOrder, ember, encodePreset, encodeTheme, fern, generateTheme, graphite, hexToOklch, indigo, ink, isLayerVisible, isStockLayerOrder, isStockLayers, isThemePresetCode, jade, layerGroupOf, lilac, linen, makeFlavor, mergeRecipe, mist, normalizeThemeBase, oklchToHex, paper, peach, presetId, registryThemeKey, resolveTheme, rose, sandstone, seedsFromPalette, shuffleSeeds, sky, validateTheme, verdant, wave };
|
package/dist/index.js
CHANGED
|
@@ -2139,14 +2139,13 @@ function buildRecipes(r) {
|
|
|
2139
2139
|
};
|
|
2140
2140
|
const PASTEL_DARK = {
|
|
2141
2141
|
background: r.lilac[1e3],
|
|
2142
|
-
|
|
2143
|
-
//
|
|
2144
|
-
//
|
|
2145
|
-
//
|
|
2146
|
-
//
|
|
2147
|
-
//
|
|
2148
|
-
|
|
2149
|
-
water: r.cobalt[950],
|
|
2142
|
+
earth: r.lilac[950],
|
|
2143
|
+
// Water lighter than land, which `blueprint`, `tropic` and `bold` already do: the three
|
|
2144
|
+
// styles whose water is the thing you remember about them. This one's is periwinkle, and at
|
|
2145
|
+
// cobalt[950] the dark half had turned it near-black, so the name stopped being true after
|
|
2146
|
+
// sundown. Lifting it also unpins the ground, which had to sit at `orchid`'s lilac[900]
|
|
2147
|
+
// because the only free step below was within 1.01:1 of that near-black water.
|
|
2148
|
+
water: r.cobalt[800],
|
|
2150
2149
|
parkA: r.jade[850],
|
|
2151
2150
|
parkB: r.jade[800],
|
|
2152
2151
|
woodA: r.fern[800],
|
|
@@ -2183,18 +2182,18 @@ function buildRecipes(r) {
|
|
|
2183
2182
|
bridgeCasing: r.lilac[1e3],
|
|
2184
2183
|
labels: {
|
|
2185
2184
|
city: r.lilac[25],
|
|
2186
|
-
cityHalo: r.lilac[
|
|
2185
|
+
cityHalo: r.lilac[950],
|
|
2187
2186
|
state: r.lilac[300],
|
|
2188
|
-
stateHalo: r.lilac[
|
|
2187
|
+
stateHalo: r.lilac[950],
|
|
2189
2188
|
country: r.lilac[300],
|
|
2190
2189
|
subplace: r.lilac[300],
|
|
2191
|
-
subplaceHalo: r.lilac[
|
|
2190
|
+
subplaceHalo: r.lilac[950],
|
|
2192
2191
|
address: r.lilac[400],
|
|
2193
|
-
addressHalo: r.lilac[
|
|
2192
|
+
addressHalo: r.lilac[950],
|
|
2194
2193
|
roadMinor: r.lilac[400],
|
|
2195
|
-
roadMinorHalo: r.lilac[
|
|
2194
|
+
roadMinorHalo: r.lilac[950],
|
|
2196
2195
|
roadMajor: r.lilac[100],
|
|
2197
|
-
roadMajorHalo: r.lilac[
|
|
2196
|
+
roadMajorHalo: r.lilac[950],
|
|
2198
2197
|
ocean: r.cobalt[400]
|
|
2199
2198
|
},
|
|
2200
2199
|
pois: {
|
|
@@ -3165,6 +3164,77 @@ async function decodeDeflate(code) {
|
|
|
3165
3164
|
}
|
|
3166
3165
|
return validateTheme(parsed);
|
|
3167
3166
|
}
|
|
3167
|
+
|
|
3168
|
+
// src/seeds-from-palette.ts
|
|
3169
|
+
var CHROMATIC_FLOOR = 0.04;
|
|
3170
|
+
var HUE_DEDUP = 20;
|
|
3171
|
+
var WATER_HUE = { lo: 190, hi: 270 };
|
|
3172
|
+
var NATURE_HUE = { lo: 100, hi: 170 };
|
|
3173
|
+
var DISPLAY_L = { lo: 0.35, hi: 0.7 };
|
|
3174
|
+
var wrapHue = (h) => (h % 360 + 360) % 360;
|
|
3175
|
+
var hueDelta = (a, b) => {
|
|
3176
|
+
const d = Math.abs(wrapHue(a) - wrapHue(b));
|
|
3177
|
+
return Math.min(d, 360 - d);
|
|
3178
|
+
};
|
|
3179
|
+
var inBand = (h, band) => {
|
|
3180
|
+
const hue = wrapHue(h);
|
|
3181
|
+
return hue >= band.lo && hue <= band.hi;
|
|
3182
|
+
};
|
|
3183
|
+
var normalizeHex = (hex) => {
|
|
3184
|
+
const raw = hex.startsWith("#") ? hex.slice(1) : hex;
|
|
3185
|
+
return `#${raw.slice(0, 6).toUpperCase()}`;
|
|
3186
|
+
};
|
|
3187
|
+
var parse = (color) => {
|
|
3188
|
+
if (!/^#?[0-9a-fA-F]{6}/.test(color.hex)) return null;
|
|
3189
|
+
const hex = normalizeHex(color.hex);
|
|
3190
|
+
const { l, c, h } = hexToOklch(hex);
|
|
3191
|
+
if (!Number.isFinite(l) || !Number.isFinite(c) || !Number.isFinite(h)) return null;
|
|
3192
|
+
return { hex, proportion: Math.max(color.proportion, 0), l, c, h, score: 0 };
|
|
3193
|
+
};
|
|
3194
|
+
var displaySeed = (color) => oklchToHex({
|
|
3195
|
+
l: Math.min(DISPLAY_L.hi, Math.max(DISPLAY_L.lo, color.l)),
|
|
3196
|
+
c: color.c,
|
|
3197
|
+
h: color.h
|
|
3198
|
+
});
|
|
3199
|
+
var byScore = (a, b) => b.score - a.score || b.proportion - a.proportion || a.hex.localeCompare(b.hex);
|
|
3200
|
+
var distinctHues = (ranked) => {
|
|
3201
|
+
const out = [];
|
|
3202
|
+
for (const color of ranked) {
|
|
3203
|
+
if (out.some((kept) => hueDelta(kept.h, color.h) < HUE_DEDUP)) continue;
|
|
3204
|
+
out.push(color);
|
|
3205
|
+
}
|
|
3206
|
+
return out;
|
|
3207
|
+
};
|
|
3208
|
+
var pickInBand = (candidates, band) => candidates.find((color) => inBand(color.h, band));
|
|
3209
|
+
function fromNeutrals(neutrals) {
|
|
3210
|
+
const mid = neutrals.slice().sort((a, b) => Math.abs(a.l - 0.5) - Math.abs(b.l - 0.5))[0] ?? parse({ hex: "#808080", proportion: 1 });
|
|
3211
|
+
const grey = displaySeed(mid);
|
|
3212
|
+
return { land: grey, water: grey, nature: grey, accent: DEFAULT_SEEDS.accent };
|
|
3213
|
+
}
|
|
3214
|
+
function seedsFromPalette(colors) {
|
|
3215
|
+
const parsed = colors.map(parse).filter((c) => c !== null);
|
|
3216
|
+
if (parsed.length === 0) return { ...DEFAULT_SEEDS };
|
|
3217
|
+
const chromatic = parsed.filter((c) => c.c >= CHROMATIC_FLOOR);
|
|
3218
|
+
if (chromatic.length === 0) return fromNeutrals(parsed);
|
|
3219
|
+
const total = chromatic.reduce((sum, c) => sum + c.proportion, 0) || 1;
|
|
3220
|
+
for (const color of chromatic) {
|
|
3221
|
+
color.score = 0.7 * (color.proportion / total) + 0.3 * Math.min(color.c / 0.15, 1);
|
|
3222
|
+
}
|
|
3223
|
+
const ranked = chromatic.slice().sort(byScore);
|
|
3224
|
+
const distinct = distinctHues(ranked);
|
|
3225
|
+
const land = distinct[0];
|
|
3226
|
+
const rest = distinct.slice(1);
|
|
3227
|
+
const water = pickInBand(rest, WATER_HUE) ?? rest[0] ?? land;
|
|
3228
|
+
const afterWater = distinct.filter((c) => c !== land && c !== water);
|
|
3229
|
+
const nature = pickInBand(afterWater, NATURE_HUE) ?? afterWater[0] ?? land;
|
|
3230
|
+
const accent = ranked.slice().sort((a, b) => b.c - a.c || byScore(a, b))[0];
|
|
3231
|
+
return {
|
|
3232
|
+
land: displaySeed(land),
|
|
3233
|
+
water: displaySeed(water),
|
|
3234
|
+
nature: displaySeed(nature),
|
|
3235
|
+
accent: accent.hex
|
|
3236
|
+
};
|
|
3237
|
+
}
|
|
3168
3238
|
export {
|
|
3169
3239
|
BUILDINGS_3D_LAYER_ID,
|
|
3170
3240
|
DEFAULT_LAYER_VISIBILITY,
|
|
@@ -3225,6 +3295,7 @@ export {
|
|
|
3225
3295
|
resolveTheme,
|
|
3226
3296
|
rose,
|
|
3227
3297
|
sandstone,
|
|
3298
|
+
seedsFromPalette,
|
|
3228
3299
|
shuffleSeeds,
|
|
3229
3300
|
sky,
|
|
3230
3301
|
validateTheme,
|