Ability to pin hue so that colors don't jump to another scale when pinned

This commit is contained in:
Lea Verou
2025-03-16 23:06:47 -04:00
parent c9a1e21cdb
commit f369916f01
4 changed files with 42 additions and 10 deletions

View File

@@ -178,7 +178,7 @@
<color-popup :title="capitalize(hue) + ' ' + tint" :token="`--wa-color-${ hue }-${ tint }`" :color="colors[hue][tint]"
:pinned="!!seedColors[colorToIndex[hue][tint]]"
:deletable="isCustom" @delete="deleteColor(colorToIndex[hue][tint])"
:pinnable="isCustom" @pin="addColor(colors[hue][tint] + '')">
:pinnable="isCustom" @pin="addColor({hue, pinnedHue: hue, level: tint})">
<div slot="trigger" class="color swatch" :style="{ colorScheme: tint > 60 ? 'light' : 'dark' }">
<wa-icon class="pinned-icon" name="thumbtack" variant="regular" v-if="seedColors[colorToIndex[hue][tint]]"></wa-icon>
<wa-icon name="sliders-simple" class="tweak-icon"></wa-icon>
@@ -187,7 +187,7 @@
<color-slider v-if="isCustom && seedHues[hue] && (tint == '95' || tint == '05' || seedColors[colorToIndex[hue][tint]]) && tweakBase[hue][tint]"
v-model:color="colors[hue][tint]"
:default-value="colors[hue][tweakBase[hue][tint]].oklch.h"
@input="!seedColors[colorToIndex[hue][tint]] ? addColor({hue, level: tint}) : null"
@input="!seedColors[colorToIndex[hue][tint]] ? addColor({hue, pinnedHue: hue, level: tint}) : null"
coord="h"
:min="HUE_RANGES[hue].mid - 70" :max="HUE_RANGES[hue].mid + 70" :step="1"
label="Hue shift" :label-min="moreHue[hueBefore[hue]]" :label-max="moreHue[hueAfter[hue]]"

View File

@@ -33,7 +33,13 @@ export default class Permalink extends URLSearchParams {
value = value.slice();
for (let v of value) {
super.append(key, v);
if (v || v === 0) {
if (typeof v === 'object') {
super.append(key, JSON.stringify(v));
} else {
super.append(key, v);
}
}
}
} else if (value === null) {
super.delete(key);

View File

@@ -92,7 +92,17 @@ let paletteAppSpec = {
}
if (this.permalink.has('color')) {
this.seedColors = this.permalink.getAll('color').map(value => ({ value }));
this.seedColors = this.permalink.getAll('color').map(value => {
if (value.startsWith('{')) {
try {
return JSON.parse(value);
} catch (e) {
return { value };
}
} else {
return { value };
}
});
}
if (this.permalink.has('uid')) {
@@ -245,7 +255,14 @@ let paletteAppSpec = {
},
seedColorValues() {
return this.seedColors.map(c => c.value);
return this.seedColors.map(c => {
if (c.pinnedHue) {
let { value, pinnedHue } = c;
return { value, pinnedHue };
} else {
return c.value;
}
});
},
seedColorObjectsRaw() {
@@ -877,11 +894,12 @@ let paletteAppSpec = {
addColor(value = this.seedColorSamples.shift() ?? '') {
if (value?.hue) {
let hue = value.hue;
// Pinning a generated color
let level = value.level ?? this.coreLevels[hue];
let { hue, level, pinnedHue } = value;
level ??= this.coreLevels[hue];
let color = this.colors[hue][level];
value = { value: color + '', color };
value = { value: color + '', color, pinnedHue };
} else {
value = typeof value === 'string' || value?.constructor.name === 'Color' ? { value } : value;
}

View File

@@ -56,6 +56,7 @@ const expose = [
'inputColorRaw',
'inputColor',
'hue',
'pinnedHue',
'level',
'tweaked',
];
@@ -100,6 +101,7 @@ export default {
inputValueRaw,
inputValue: inputColor ? inputValueRaw : undefined,
inputColor,
pinnedHue: this.modelValue.pinnedHue,
editing: 0,
inputFocused: false,
watching: {},
@@ -143,10 +145,16 @@ export default {
colorInfo() {
if (!this.color) {
return { hue: undefined, level: undefined };
return { hue: this.pinnedHue, level: undefined };
}
return identifyColor(this.color, this.otherColors);
let ret = identifyColor(this.color, this.otherColors);
if (this.pinnedHue) {
ret.hue = this.pinnedHue;
}
return ret;
},
hue() {