-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<color-gamut> prototype, used by <css-color>
- Loading branch information
Showing
9 changed files
with
253 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
body_classes: cn-ignore | ||
--- | ||
<script src="color-gamut.js" type="module"></script> | ||
# <color-gamut> | ||
|
||
Gamut indicator. Used internally by `<css-color>` | ||
|
||
## Usage | ||
|
||
Static (only read once): | ||
```html | ||
<color-gamut>red</color-gamut> | ||
``` | ||
|
||
Produces <color-gamut>red</color-gamut> | ||
|
||
Dynamic: | ||
```js | ||
colorGamutElement.color = colorValue; | ||
``` | ||
|
||
## Demo | ||
|
||
<form id=params> | ||
<code>oklch(<input type=number id=l value=50>% <input type=number id=min_c value=30>–<input type=number id=max_c value=40>% <input type=number id=h value=50>)</code> | ||
<p><label>Chroma increments: <input type=number id=c_step value="0.2" min="0">%</label> | ||
</form> | ||
|
||
<script type=module> | ||
params.addEventListener("input", e => { | ||
let c_range = {min: Number(min_c.value), max: Number(max_c.value)}; | ||
let step = Number(c_step.value); | ||
let colors = []; | ||
for (let c = c_range.min; c<= c_range.max; c+=step) { | ||
colors.push(`oklch(${l.value}% ${c.toLocaleString("en")}% ${h.value})`); | ||
} | ||
|
||
colors_tbody.innerHTML = colors.map(color => ` | ||
<tr> | ||
<td> | ||
<code>${color}</code> | ||
</td> | ||
<td> | ||
<color-gamut>${color}</color-gamut> | ||
</td> | ||
</tr>`).join("\n"); | ||
}); | ||
params.dispatchEvent(new Event("input")); | ||
</script> | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<th>Color</th> | ||
<th>Gamut</th> | ||
</tr> | ||
</thead> | ||
<tbody id=colors_tbody> | ||
</tbody> | ||
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import Color from "../../dist/color.js"; | ||
|
||
const gamuts = ["srgb", "p3", "rec2020"]; | ||
|
||
let styleURL = new URL("./style.css", import.meta.url); | ||
|
||
export default class ColorGamut extends HTMLElement { | ||
#label; | ||
|
||
constructor () { | ||
super(); | ||
this.attachShadow({mode: "open"}); | ||
this.shadowRoot.innerHTML = ` | ||
<style>@import url("${ styleURL }")</style> | ||
<span id="label" part="label"></span> | ||
`; | ||
|
||
this.attributeChangedCallback(); | ||
|
||
let textContent = this.textContent; | ||
|
||
if (textContent) { | ||
this.color ??= this.textContent; | ||
} | ||
} | ||
|
||
connectedCallback () { | ||
this.#render(); | ||
} | ||
|
||
#render () { | ||
if (!this.isConnected) { | ||
return; | ||
} | ||
|
||
if (!this.#label) { | ||
this.#label = this.shadowRoot.querySelector("#label"); | ||
} | ||
|
||
if (this.#color) { | ||
let gamut = null; | ||
|
||
for (let g in this.gamuts) { | ||
if (this.#color.inGamut(g)) { | ||
gamut = g; | ||
break; | ||
} | ||
} | ||
|
||
this.#setGamut(gamut); | ||
} | ||
else { | ||
this.#setGamut(); | ||
} | ||
} | ||
|
||
#gamut; | ||
get gamut () { | ||
return this.#gamut; | ||
} | ||
|
||
#setGamut (gamut) { | ||
this.#gamut = gamut; | ||
|
||
if (gamut === undefined) { | ||
this.removeAttribute("gamut"); | ||
this.style.removeProperty("--gamut-level"); | ||
this.#label.textContent = ""; | ||
return; | ||
} | ||
|
||
let label = ""; | ||
let level = -1; | ||
let levels = Object.entries(this.gamuts); | ||
if (gamut === null) { | ||
// Outside all gamuts | ||
this.setAttribute("gamut", "none"); | ||
level = levels.length; | ||
label = levels.at(-1)[1] + "+"; | ||
} | ||
else { | ||
this.setAttribute("gamut", gamut); | ||
label = this.gamuts[gamut]; | ||
level = levels.findIndex(([id]) => id === gamut); | ||
} | ||
|
||
this.#label.textContent = label; | ||
this.style.setProperty("--gamut-level", level); | ||
} | ||
|
||
#color; | ||
get color () { | ||
return this.#color; | ||
} | ||
|
||
set color (color) { | ||
if (!(color instanceof Color)) { | ||
color = new Color(color); | ||
} | ||
|
||
this.#color = color; | ||
this.#render(); | ||
} | ||
|
||
static observedAttributes = ["gamuts"]; | ||
static defaultGamuts = ["srgb", "p3", "rec2020"]; | ||
|
||
attributeChangedCallback (name, oldValue, newValue) { | ||
if (!name || name === "gamuts") { | ||
if (newValue === undefined) { | ||
newValue = this.getAttribute("gamuts"); | ||
} | ||
|
||
if (oldValue !== newValue) { | ||
this.gamuts = this.constructor.parseGamuts(newValue ?? this.constructor.defaultGamuts); | ||
this.#render(); | ||
} | ||
} | ||
} | ||
|
||
static parseGamuts (gamuts) { | ||
if (typeof gamuts === "string") { | ||
gamuts = gamuts.trim().split(/\s*,\s*/); | ||
} | ||
|
||
return Object.fromEntries(gamuts.map(gamut => { | ||
gamut = gamut.trim(); | ||
let [id, label = Color.spaces[gamut]?.name ?? gamut] = gamut.split(/\s*:\s*/); | ||
return [id, label]; | ||
})); | ||
|
||
} | ||
} | ||
|
||
customElements.define("color-gamut", ColorGamut); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
:host { | ||
display: inline-flex; | ||
align-items: center; | ||
justify-content: center; | ||
border-radius: .2em; | ||
color: white; | ||
background: var(--gamut-color, var(--color-neutral-60, hsl(220 10% 60%))); | ||
font-weight: bold; | ||
padding-inline: .4em; | ||
line-height: 1.4; | ||
} | ||
|
||
:host([gamut="p3"]) { | ||
color: black; | ||
} | ||
|
||
:host([gamut="srgb"]) { | ||
--gamut-color: var(--color-green, yellowgreen); | ||
} | ||
|
||
:host([gamut="p3"]) { | ||
--gamut-color: var(--color-yellow, gold); | ||
} | ||
|
||
:host([gamut="rec2020"]) { | ||
--gamut-color: var(--color-orange, orange); | ||
} | ||
|
||
:host([gamut="none"]) { | ||
--gamut-color: var(--color-red, red); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.