Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e13ef18
[color-swatch] Add support for deltas from other color
DmitrySharabin Jun 11, 2024
d6c7f7f
[color-scale] Add support for deltas from other color
DmitrySharabin Jun 11, 2024
8b85dff
Merge branch 'main' into color-swatch-deltas
DmitrySharabin Jun 11, 2024
4525cff
Move vars to the block where they are used
DmitrySharabin Jun 11, 2024
e642891
Don't show the delta if it's zero
DmitrySharabin Jun 11, 2024
85428d8
Minor refactor
DmitrySharabin Jun 11, 2024
6242c06
Support different precision for angles and numbers
DmitrySharabin Jun 11, 2024
9c88652
Add support for the primary use case
DmitrySharabin Jun 11, 2024
bd4df34
🤦‍♂️
DmitrySharabin Jun 11, 2024
5ddf3a1
Increase precision for percents
DmitrySharabin Jun 11, 2024
fea82ad
[color-swatch] Add docs on the `vs` prop (attribute)
DmitrySharabin Jun 12, 2024
5cfe1b5
[color-scale] Add docs on the `coords`, `deltas`, and `vs` attributes
DmitrySharabin Jun 12, 2024
58974c4
Address feedback
DmitrySharabin Jun 12, 2024
84ff6d3
Address feedback
DmitrySharabin Jun 12, 2024
6746cd4
Oops
DmitrySharabin Jun 12, 2024
bdc2ac9
Add links to the page with ΔE algorithms
DmitrySharabin Jun 12, 2024
43fb65b
Update the docs
DmitrySharabin Jun 12, 2024
d278303
Manually calculate deltas
DmitrySharabin Jun 12, 2024
89fdb92
Move to a more appropriate place
DmitrySharabin Jun 12, 2024
5ca9abd
Merge branch 'main' into color-swatch-deltas
DmitrySharabin Jun 13, 2024
1aa5bbe
Merge branch 'main' into color-swatch-deltas
DmitrySharabin Jun 17, 2024
fdcfb61
Leftovers from merging the main branch
DmitrySharabin Jun 17, 2024
9482bcf
Add support for deltaE and contrast
DmitrySharabin Jun 17, 2024
de58fc4
Fix comment
DmitrySharabin Jun 17, 2024
5dfb4a6
Update README.md
DmitrySharabin Jun 17, 2024
a151249
Merge branch 'main' into color-swatch-deltas
DmitrySharabin Jun 17, 2024
09f4136
Update API
DmitrySharabin Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/color-scale/color-scale.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ const Self = class ColorScale extends NudeElement {
if (this.coords) {
swatch.coords = this.coords;
}
if (this.vs) {
swatch.vs = this.vs;
}
i++;
}

Expand Down Expand Up @@ -152,6 +155,9 @@ const Self = class ColorScale extends NudeElement {
additionalDependencies: ["coords"],
},
coords: {},
vs: {
type: Color,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see why you're doing the #hasVs thing. That’s not the right way; it means that if someone sets it via the property you get a different behavior. You want two properties: one for the raw value, and one for the parsed value, which is either true (previous color), false (no vs), or a Color instance.

And yes, this is another case of rawProp.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm doing this precisely because I can't see another way to distinguish different cases: color, no color, no vs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option would be to use a custom parse function. Up to you.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it may be useful to provide a way to do vs with the previous or next color. In that case we could have vs="previous" and vs="next" which may be more explanatory than a bare vs with no value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option would be to use a custom parse function.

Yeah, I was going to try this later. Glad it makes sense. :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it may be useful to provide a way to do vs with the previous or next color. In that case we could have vs="previous" and vs="next" which may be more explanatory than a bare vs with no value.

I like it

},
};
}

Expand Down
57 changes: 44 additions & 13 deletions src/color-swatch/color-swatch.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
0 0 / calc(2 * var(--_transparency-cell-size)) calc(2 * var(--_transparency-cell-size))
content-box border-box var(--_transparency-background)
);
--_positive-deltaE-color: var(--positive-deltaE-color, hsl(120, 80%, 25%));
--_negative-deltaE-color: var(--negative-deltaE-color, hsl(0, 85%, 40%));

position: relative;
display: inline-flex;
Expand Down Expand Up @@ -49,31 +51,48 @@ slot {
}
}

[part="coords"] {
[part="coords"], [part="deltaE"] {
margin: 0;
display: inline-flex;
gap: .5em;

dd {
margin: 0;
font-weight: bold;
font-variant-numeric: tabular-nums;
}

&:is(:host([size="large"]) &) {
display: grid;
grid-template-columns: max-content auto;
gap: .1em .2em;
font-size: max(9px, 80%);
justify-content: start;

.coord {
display: contents;
}
grid-template-columns: subgrid;
}
}

[part="coords"] {
.coord {
display: flex;
gap: .2em;

dd {
margin: 0;
font-weight: bold;
font-variant-numeric: tabular-nums;
dd.deltaE {
color: var(--_deltaE-color);

&.positive {
--_deltaE-color: var(--_positive-deltaE-color);
}

&.negative {
--_deltaE-color: var(--_negative-deltaE-color);
}
}
}

&:is(:host([size="large"]) &) {
.coord {
display: contents;

dd:not(.deltaE, :has(~ dd)) {
grid-column: span 2;
}
}
}
}
Expand All @@ -97,6 +116,18 @@ slot {
@container color-swatch (width <= 5rem) {
font-size: 80%;
}

&:is(:host([size="large"]) &) {
display: grid;
grid-template-columns: repeat(3, max-content);
gap: .1em .2em;
font-size: max(9px, 80%);
justify-content: start;

& > * {
grid-column: 1 / -1;
}
}
}

[part="color-wrapper"] {
Expand Down
75 changes: 60 additions & 15 deletions src/color-swatch/color-swatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,27 +109,68 @@ const Self = class ColorSwatch extends NudeElement {
this.style.setProperty("--color", colorString);
}

if (name === "coords") {
if (!this.coords.length) {
return;
}
if (name === "coords" || name === "vs") {
if (this.coords.length) {
this._el.coords ??= Object.assign(document.createElement("dl"), {part: "coords"});
if (!this._el.coords.parentNode) {
this._el.colorWrapper.after(this._el.coords);
}

this._el.coords ??= Object.assign(document.createElement("dl"), {part: "coords"});
if (!this._el.coords.parentNode) {
this._el.colorWrapper.after(this._el.coords);
}
let coords = [];
for (let coord of this.coords) {
let [label, channel] = Object.entries(coord)[0];
let value = this.color.get(channel);

let deltaString;
if (typeof value === "number" && this.vs) {
let {space, index} = Color.Space.resolveCoord(channel);
let deltas = this.color.deltas(this.vs, this.color, {space}).coords;

let delta = deltas[index];
if (typeof delta === "number" && delta !== 0) {
let spaceCoord = Object.values(space.coords)[index];
let isAngle = spaceCoord.type === "angle";
if (!isAngle) {
delta = Math.abs(delta - value) / delta;
}
delta = Number(delta.toPrecision(isAngle ? 4 : 1));

let sign = delta > 0 ? "+" : "";
let className = delta > 0 ? "positive" : "negative";
deltaString = `<dd class="deltaE ${ className }">(${ sign }${ delta }${ !isAngle ? "%" : ""})</dd>`;
}
}

value = typeof value === "number" ? Number(value.toPrecision(4)) : value;
let html = `<dt>${ label }</dt><dd>${ value }</dd>`;
if (deltaString) {
html += deltaString;
}

coords.push(`<div class="coord">${ html }</div>`);
}

let coords = [];
for (let coord of this.coords) {
let [label, channel] = Object.entries(coord)[0];
this._el.coords.innerHTML = coords.join("\n");
}
}

let value = this.color.get(channel);
if (name === "vs") {
if (!this.vs) {
this._el.deltaE?.remove();
this._el.deltaE = null;
}
else {
let value = this.color.deltaE(this.vs);
value = typeof value === "number" ? Number(value.toPrecision(4)) : value;
if (value !== 0) {
this._el.deltaE ??= Object.assign(document.createElement("dl"), {part: "deltaE"});
if (!this._el.deltaE.parentNode) {
(this._el.coords ?? this._el.colorWrapper).after(this._el.deltaE);
}

coords.push(`<div class="coord"><dt>${ label }</dt><dd>${ value }</dd></div>`);
this._el.deltaE.innerHTML = `<dt>ΔE</dt><dd>${ value }</dd>`;
}
}

this._el.coords.innerHTML = coords.join("\n");
}
}

Expand Down Expand Up @@ -179,6 +220,10 @@ const Self = class ColorSwatch extends NudeElement {
},
dependencies: ["color"],
},
vs: {
type: Color,
dependencies: ["color"],
},
}

static events = {
Expand Down