Public
Edited
Paused
1 fork
Importers
1 star
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
hexToP3 = (hex = "", { colorspace = "display-p3" } = {}) => {
// Calculate richer P3 colors from HEX values
try {
let count;
let alpha = false;
const { 0: match } = hex.trim().match(/^#(?:[0-9a-f]{3,4}){1,2}$/i);
switch (match.length) {
case 5: // #RGBA
alpha = true;
case 4: // #RGB
count = 1;
break;
case 9: // #RRGGBBAA
alpha = true;
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(${colorspace} ${components.slice(0, 3).join(" ")}${
alpha ? ` / ${components.slice(-1)}` : ""
})`;
} 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
);
const alpha = components[components.length - 1];
return `color(${colorspace} ${components.slice(0, 3).join(" ")}${
+alpha == alpha ? ` / ${alpha}` : ""
})`;
} catch (e) {
throw Error("Argument is not a sRGB color");
}
};
})()
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more