Public
Edited
Jul 13, 2024
Comments locked
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colors = {
const { items } = JSON.parse(tokens.textContent.trim());
yield items.map(({ name, value }) =>
Object.assign(
{
name
},
((color) => ({
hex: color.formatHex(),
rgb: color + "",
p3: hexToP3(value)
}))(d3.color(value))
)
);
}
Insert cell
Insert cell
Insert cell
hexToP3("#0f0")
Insert cell
rgbToP3("rgb(0, 255, 0)")
Insert cell
hexToP3("#0f00")
Insert cell
rgbToP3("rgba(0, 255, 0, 0%)")
Insert cell
hexToP3("#00ff00")
Insert cell
rgbToP3("rgba(none 255 none / none)")
Insert cell
hexToP3("#00ff00ff")
Insert cell
rgbToP3("rgba(0, 255, 0, 100%)")
Insert cell
rgbToP3("rgba(0, 254.9, 0, 1%)")
Insert cell
rgbToP3("rgba(., 255., 0, .)")
Insert cell
rgbToP3("rgba(none 255.0 0 / .%)")
Insert cell
Insert cell
{
/*!
* Many thanks to Dean Jackson, Nikita Vasilyev, David Darnes, and Andy Bell! - mg
*/
const color = "rgb(35, 64, 88)";
yield md`
<style>
/* sRGB color */
:root {
--salty-dog: ${color};
}

h1[id] {
color: var(--salty-dog);
}

@media (color-gamut: p3) {
/* Display P3 color, when supported */
:root {
--salty-dog: ${rgbToP3(color)};
}
}

style:only-child:before { content: "## Tweak main heading color (${hasP3})…" !important; }
</style>
`;
}
Insert cell
hasP3 = window.matchMedia("(color-gamut: p3)").matches
Insert cell
color = (values = [0, 0, 0], colorspace = "srgb") => {
const { 3: alpha = NaN, ...components } = values;
return `color(${colorspace} ${Object.values(components).join(" ")}${
+alpha == alpha ? ` / ${alpha}` : ""
})`;
}
Insert cell
hexToP3 = (hex = "", { colorspace = "display-p3" } = {}) => {
// Calculate richer P3 colors from HEX values
try {
let count;
const { 0: match } = hex.trim().match(/^#(?:[0-9a-f]{3,4}){1,2}$/i);
switch (match.length) {
case 5: // #RGBA
case 4: // #RGB
count = 1;
break;
case 9: // #RRGGBBAA
case 7: // #RRGGBB
count = 2;
break;
}
const _ = (x) => (parseInt(x, 16) / 255).toFixed(6) * 1;
const process = [(x) => _(x + x), (x) => _(x)][count - 1];
const components = match
.slice(1)
.match(new RegExp(`.{${count}}`, "g"))
.map(process);
return color(components, colorspace);
} catch (e) {
throw Error("Argument is not an hexadecimal color");
}
}
Insert cell
Insert cell
Insert cell
rgbToP3 = (() => {
const fractional = ["(?:[.]0*)?", "(?:[.]\\d*)?"];
const percentage =
"(?:100" + fractional[0] + "|[1-9]?\\d?" + fractional[1] + ")%";
const isRGB = new RegExp(
/* rgb(R G B[ / A]) | rgba(R G B[ / A]) */
[
"^rgba?\\(",
/* component values: none | 0 to 255 | 0% to 100% */
["R", "G", "B"]
.map(
(C) =>
["(?<", C, ">"].join("") +
[
"none",
"(?:255" +
fractional[0] +
"|(?:25[0-4]|2[0-4]\\d|1\\d{1,2}|[1-9]?\\d?)" +
fractional[1] +
")",
percentage
].join("|") +
")"
)
.join("(?:\\s*,\\s*|\\s+)"),
/* alpha channel value: none | 0 to 1 | 0% to 100% */
"(?:\\s*[,\\/]\\s*",
"(?<A>" +
[
"none",
"(?:1" + fractional[0] + "|0?" + fractional[1] + ")",
percentage
].join("|") +
")",
")?",
"\\)$"
].join(""),
"i"
);
return (rgba = "", { colorspace = "display-p3" } = {}) => {
// Calculate richer P3 colors from sRGB absolute values
try {
const components = rgba
.trim()
.match(isRGB)
.slice(1)
.map((x, i) =>
["none", ".", ".%"].includes(x)
? i < 3
? /* R, G, or B */ 0
: /* A */ [0, NaN][+(x === "none")]
: (
parseFloat(x, 10) /
((x || "").match(/%$/)
? /* percentage */ 100
: i < 3
? /* R, G, or B */ 255
: /* A */ 1)
).toFixed(6) * 1
);
return color(components, colorspace);
} catch (e) {
throw Error("Argument is not a sRGB color");
}
};
})()
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more