Compare commits

...

5 Commits

Author SHA1 Message Date
Leonard Hecker
5fc4bdbe7c wip 2024-09-10 23:43:11 +02:00
Leonard Hecker
a2bc5dce15 wip 2024-09-10 22:14:57 +02:00
Leonard Hecker
46c9c092da wip 2024-09-10 22:14:57 +02:00
Leonard Hecker
88422ffa25 Address feedback 2024-09-10 22:14:56 +02:00
Leonard Hecker
2beecdca1f wip 2024-09-10 22:14:56 +02:00
2 changed files with 563 additions and 36 deletions

527
doc/theme_colors.html Normal file
View File

@@ -0,0 +1,527 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Theme Color Quality Tests</title>
<script src="https://colorjs.io/dist/color.global.min.js"></script>
<script src="https://cdn.plot.ly/plotly-2.34.0.min.js"></script>
<style>
html {
background: #000;
color: #fff;
}
h2 {
font-family: monospace;
}
h2 > button {
float: right;
}
#container {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
#container > div {
width: 418px;
}
.swatch {
display: grid;
grid-template-columns: repeat(8, 50px);
gap: 2px;
border: 2px solid black;
background: black;
}
.swatch > div {
width: 50px;
height: 50px;
}
.swatch span {
display: block;
font-family: monospace;
line-height: 2;
text-align: center;
}
</style>
</head>
<body>
<div id="container"></div>
<script>(() => {
const themes = {
// Find the optimal selection color (e.g. #92a4fd):
//
// theme = ["#000000", "#be2c21", "#3fae3a", "#be9a4a", "#204dbe", "#bb54be", "#00a7b2", "#bebebe", "#808080", "#ff3e30", "#58ea51", "#ffd166", "#2f6aff", "#fc74ff", "#00e1f0", "#ffffff"]
// theme = theme.map(t => Color.to(t, "oklab"))
//
// optD = 0;
// opt = null;
//
// for (let h = 264-10; h <= 264+10; h += 1) {
// for (let c = 10; c <= 100; c += 1) {
// for (let l = 40; l <= 90; l += 1) {
// const col = Color.to(`color(--okhsl ${h} ${c}% ${l}%)`, "oklab");
// }
// }
// }
"Prototype Bright": (() => {
const bright_red = new Color(`color(--okhsl ${Color.to("#f00", "okhsl").h} 100% 60.15%)`);
const bright_green = new Color(`color(--okhsl ${Color.to("#0f0", "okhsl").h} 92.5% 80%)`);
const bright_blue = new Color(`color(--okhsl ${Color.to("#00f", "okhsl").h} 100% 51.2%)`);
const mixOpts = { space: "oklab", outputSpace: "okhsl" };
const bright_yellow = new Color(`color(--okhsl ${bright_red.mix(bright_green, 0.5, mixOpts).h} 100% 84%)`);
const bright_purple = new Color(`color(--okhsl ${bright_blue.mix(bright_red, 0.5, mixOpts).h} 100% 73%)`);
const bright_cyan = new Color(`color(--okhsl ${bright_green.mix(bright_blue, 0.5, mixOpts).h} 100% 80%)`);
const bright = [
new Color("oklch(60% 0 0)"),
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_purple,
bright_cyan,
new Color("oklch(100% 0 0)"),
];
const dark = [
new Color("oklch(0% 0 0)"),
...bright.slice(1, 8).map(c => c.mix("#000", 0.2, { space: "oklab" })),
];
return dark.concat(...bright).map(c => c.to("sRGB").toString({
format: "hex",
collapse: false
}))
})(),
// https://oklch.com/
"Prototype Symmetric": [
new Color("oklch(0% 0 0)"), // Black
new Color("oklch(60% 0.098 30)"), // Red
new Color("oklch(60% 0.098 150)"), // Green
new Color("oklch(60% 0.098 90)"), // Yellow
new Color("oklch(60% 0.098 270)"), // Blue
new Color("oklch(60% 0.098 330)"), // Purple
new Color("oklch(60% 0.098 210)"), // Cyan
new Color("oklch(80% 0 0)"), // White
new Color("oklch(40% 0 0)"), // Bright Black
new Color("oklch(80% 0.098 30)"), // Bright Red
new Color("oklch(80% 0.098 150)"), // Bright Green
new Color("oklch(80% 0.098 90)"), // Bright Yellow
new Color("oklch(80% 0.098 270)"), // Bright Blue
new Color("oklch(80% 0.098 330)"), // Bright Purple
new Color("oklch(80% 0.098 210)"), // Bright Cyan
new Color("oklch(100% 0 0)"), // Bright White
].map(c => c.to("sRGB").toString({ format: "hex", collapse: false })),
"Terminal.app": [
"#000000",
"#990000",
"#00a600",
"#999900",
"#0000b2",
"#b200b2",
"#00a6b2",
"#bfbfbf",
"#666666",
"#e50000",
"#00d900",
"#e5e500",
"#0000ff",
"#e500e5",
"#00e5e5",
"#e5e5e5",
],
"Windows NT": [
"#000000",
"#800000",
"#008000",
"#808000",
"#000080",
"#800080",
"#008080",
"#C0C0C0",
"#808080",
"#FF0000",
"#00FF00",
"#FFFF00",
"#0000FF",
"#FF00FF",
"#00FFFF",
"#FFFFFF",
],
"Windows XP": [
"#000000",
"#A80000",
"#00A800",
"#A85400",
"#0000A8",
"#A800A8",
"#61D6D6",
"#A8A8A8",
"#545454",
"#FF0000",
"#00FF00",
"#FFFF00",
"#0000FF",
"#FF00FF",
"#00FFFF",
"#FFFFFF",
],
"URXVT": [
"#000000",
"#BE0000",
"#00BE00",
"#BEBE00",
"#0000BE",
"#BE00BE",
"#00BEBE",
"#BEBEBE",
"#424242",
"#FF0000",
"#00FF00",
"#FFFF00",
"#0000FF",
"#FF00FF",
"#00FFFF",
"#FFFFFF",
],
"Campbell": [
"#0C0C0C",
"#C50F1F",
"#13A10E",
"#C19C00",
"#0037DA",
"#881798",
"#3A96DD",
"#CCCCCC",
"#767676",
"#E74856",
"#16C60C",
"#F9F1A5",
"#3B78FF",
"#B4009E",
"#61D6D6",
"#F2F2F2",
],
"Campbell Powershell": [
"#0C0C0C",
"#C50F1F",
"#13A10E",
"#C19C00",
"#0037DA",
"#881798",
"#3A96DD",
"#CCCCCC",
"#767676",
"#E74856",
"#16C60C",
"#F9F1A5",
"#3B78FF",
"#B4009E",
"#61D6D6",
"#F2F2F2",
],
"One Half Dark": [
"#282C34",
"#E06C75",
"#98C379",
"#E5C07B",
"#61AFEF",
"#C678DD",
"#56B6C2",
"#DCDFE4",
"#5A6374",
"#E06C75",
"#98C379",
"#E5C07B",
"#61AFEF",
"#C678DD",
"#56B6C2",
"#DCDFE4",
],
"One Half Light": [
"#383A42",
"#E45649",
"#50A14F",
"#C18301",
"#0184BC",
"#A626A4",
"#0997B3",
"#FAFAFA",
"#4F525D",
"#DF6C75",
"#98C379",
"#E4C07A",
"#61AFEF",
"#C577DD",
"#56B5C1",
"#FFFFFF",
],
"Solarized Dark": [
"#002B36",
"#DC322F",
"#859900",
"#B58900",
"#268BD2",
"#D33682",
"#2AA198",
"#EEE8D5",
"#073642",
"#CB4B16",
"#586E75",
"#657B83",
"#839496",
"#6C71C4",
"#93A1A1",
"#FDF6E3",
],
"Solarized Light": [
"#002B36",
"#DC322F",
"#859900",
"#B58900",
"#268BD2",
"#D33682",
"#2AA198",
"#EEE8D5",
"#073642",
"#CB4B16",
"#586E75",
"#657B83",
"#839496",
"#6C71C4",
"#93A1A1",
"#FDF6E3",
],
"Tango Dark": [
"#000000",
"#CC0000",
"#4E9A06",
"#C4A000",
"#3465A4",
"#75507B",
"#06989A",
"#D3D7CF",
"#555753",
"#EF2929",
"#8AE234",
"#FCE94F",
"#729FCF",
"#AD7FA8",
"#34E2E2",
"#EEEEEC",
],
"Tango Light": [
"#000000",
"#CC0000",
"#4E9A06",
"#C4A000",
"#3465A4",
"#75507B",
"#06989A",
"#D3D7CF",
"#555753",
"#EF2929",
"#8AE234",
"#FCE94F",
"#729FCF",
"#AD7FA8",
"#34E2E2",
"#EEEEEC",
],
"Dark+": [
"#000000",
"#cd3131",
"#0dbc79",
"#e5e510",
"#2472c8",
"#bc3fbc",
"#11a8cd",
"#e5e5e5",
"#666666",
"#f14c4c",
"#23d18b",
"#f5f543",
"#3b8eea",
"#d670d6",
"#29b8db",
"#e5e5e5",
],
"CGA": [
"#000000",
"#AA0000",
"#00AA00",
"#AA5500",
"#0000AA",
"#AA00AA",
"#00AAAA",
"#AAAAAA",
"#555555",
"#FF5555",
"#55FF55",
"#FFFF55",
"#5555FF",
"#FF55FF",
"#55FFFF",
"#FFFFFF",
],
"IBM 5153": [
"#000000",
"#AA0000",
"#00AA00",
"#C47E00",
"#0000AA",
"#AA00AA",
"#00AAAA",
"#AAAAAA",
"#555555",
"#FF5555",
"#55FF55",
"#FFFF55",
"#5555FF",
"#FF55FF",
"#55FFFF",
"#FFFFFF",
],
};
Object.entries(themes).forEach(([name, srgb]) => {
const oklch = srgb.map(c => Color.to(c, "Oklch"));
const title = document.createElement("h2");
title.innerText = name;
const download = document.createElement("button");
download.type = "button";
download.innerText = "Copy";
download.onclick = () => {
navigator.clipboard.writeText(JSON.stringify({
name,
background: srgb[0],
foreground: srgb[7],
cursorColor: "#ffffff",
black: srgb[0],
red: srgb[1],
green: srgb[2],
yellow: srgb[3],
blue: srgb[4],
purple: srgb[5],
cyan: srgb[6],
white: srgb[7],
brightBlack: srgb[8],
brightRed: srgb[9],
brightGreen: srgb[10],
brightYellow: srgb[11],
brightBlue: srgb[12],
brightPurple: srgb[13],
brightCyan: srgb[14],
brightWhite: srgb[15],
}, null, 4));
download.innerText = "Copied!";
download.disabled = true;
setTimeout(() => {
download.innerText = "Copy";
download.disabled = false;
}, 1000);
}
title.appendChild(download);
const swatch = document.createElement("div");
swatch.className = "swatch";
for (let i = 0; i < 16; ++i) {
const span = document.createElement("span");
span.innerText = oklch[i].l.toFixed(3);
span.style.color = srgb[i];
span.style.background = srgb[0];
const div = document.createElement("div");
div.style.background = srgb[i];
div.appendChild(span);
swatch.appendChild(div);
}
const plot = document.createElement("div");
Plotly.newPlot(plot, [{
type: "scatterpolar",
mode: "lines",
hoverinfo: "skip",
showlegend: false,
theta: Array.from({ length: 360 }, (x, i) => i),
// Pre-calculated max. chroma per hue for sRGB colors.
r: [0.260, 0.258, 0.258, 0.257, 0.257, 0.257, 0.256, 0.256, 0.256, 0.255, 0.254, 0.253, 0.252, 0.251, 0.251, 0.251, 0.252, 0.252, 0.252, 0.252, 0.253, 0.253, 0.253, 0.254, 0.254, 0.255, 0.255, 0.255, 0.255, 0.255, 0.252, 0.246, 0.242, 0.237, 0.233, 0.229, 0.226, 0.221, 0.219, 0.214, 0.213, 0.209, 0.207, 0.204, 0.201, 0.200, 0.196, 0.196, 0.193, 0.190, 0.190, 0.187, 0.185, 0.185, 0.182, 0.182, 0.181, 0.179, 0.179, 0.177, 0.175, 0.176, 0.174, 0.173, 0.174, 0.172, 0.171, 0.172, 0.171, 0.170, 0.171, 0.170, 0.169, 0.170, 0.169, 0.168, 0.170, 0.169, 0.168, 0.170, 0.169, 0.170, 0.171, 0.170, 0.172, 0.172, 0.171, 0.173, 0.173, 0.175, 0.175, 0.175, 0.177, 0.178, 0.180, 0.180, 0.182, 0.183, 0.184, 0.186, 0.187, 0.189, 0.192, 0.193, 0.196, 0.197, 0.200, 0.201, 0.204, 0.208, 0.209, 0.210, 0.212, 0.211, 0.213, 0.215, 0.217, 0.216, 0.218, 0.220, 0.221, 0.223, 0.225, 0.228, 0.228, 0.231, 0.234, 0.234, 0.237, 0.241, 0.244, 0.245, 0.249, 0.253, 0.255, 0.259, 0.264, 0.266, 0.271, 0.276, 0.280, 0.286, 0.289, 0.287, 0.278, 0.271, 0.265, 0.258, 0.251, 0.245, 0.239, 0.234, 0.228, 0.223, 0.219, 0.215, 0.211, 0.209, 0.205, 0.202, 0.199, 0.195, 0.192, 0.190, 0.187, 0.185, 0.182, 0.180, 0.178, 0.176, 0.175, 0.174, 0.172, 0.170, 0.169, 0.167, 0.166, 0.165, 0.163, 0.162, 0.161, 0.160, 0.159, 0.158, 0.157, 0.156, 0.157, 0.157, 0.156, 0.155, 0.155, 0.154, 0.154, 0.154, 0.153, 0.153, 0.153, 0.151, 0.151, 0.149, 0.149, 0.147, 0.148, 0.147, 0.146, 0.146, 0.145, 0.145, 0.145, 0.144, 0.145, 0.144, 0.144, 0.144, 0.144, 0.144, 0.143, 0.144, 0.145, 0.144, 0.145, 0.145, 0.145, 0.147, 0.146, 0.147, 0.147, 0.148, 0.15, 0.149, 0.151, 0.151, 0.153, 0.154, 0.154, 0.156, 0.157, 0.159, 0.159, 0.162, 0.162, 0.165, 0.166, 0.169, 0.17, 0.173, 0.174, 0.178, 0.18, 0.182, 0.186, 0.189, 0.192, 0.197, 0.2, 0.204, 0.208, 0.213, 0.219, 0.224, 0.232, 0.242, 0.249, 0.262, 0.284, 0.308, 0.307, 0.307, 0.306, 0.304, 0.301, 0.301, 0.302, 0.3, 0.297, 0.297, 0.298, 0.296, 0.294, 0.294, 0.295, 0.294, 0.292, 0.292, 0.294, 0.292, 0.290, 0.292, 0.292, 0.29, 0.291, 0.292, 0.290, 0.291, 0.292, 0.291, 0.291, 0.293, 0.291, 0.293, 0.293, 0.292, 0.295, 0.294, 0.295, 0.296, 0.295, 0.298, 0.296, 0.299, 0.298, 0.301, 0.300, 0.303, 0.302, 0.305, 0.303, 0.307, 0.305, 0.308, 0.308, 0.310, 0.313, 0.311, 0.314, 0.316, 0.316, 0.319, 0.320, 0.320, 0.314, 0.312, 0.311, 0.309, 0.303, 0.302, 0.300, 0.299, 0.296, 0.292, 0.291, 0.289, 0.288, 0.287, 0.283, 0.280, 0.279, 0.278, 0.277, 0.276, 0.274, 0.271, 0.269, 0.268, 0.267, 0.266, 0.266, 0.265, 0.264, 0.262],
marker: {
color: srgb[7],
},
}, {
type: "scatterpolar",
mode: "markers+text",
hoverinfo: "r+theta+text",
showlegend: false,
hovertext: [
"Black",
"Red",
"Green",
"Yellow",
"Blue",
"Purple",
"Cyan",
"White",
"Bright Black",
"Bright Red",
"Bright Green",
"Bright Yellow",
"Bright Blue",
"Bright Purple",
"Bright Cyan",
"Bright White",
],
marker: {
color: srgb,
size: 12,
},
theta: oklch.map(c => c.h),
r: oklch.map(c => c.c),
}], {
width: 418,
height: 418,
margin: {
l: 40,
r: 40,
b: 40,
t: 40,
},
paper_bgcolor: "#000",
polar: {
bgcolor: srgb[0],
angularaxis: {
color: srgb[7],
gridcolor: srgb[8],
},
radialaxis: {
color: srgb[7],
gridcolor: srgb[8],
range: [0, 0.4],
},
},
});
const theme = document.createElement("div");
theme.appendChild(title);
theme.appendChild(swatch);
theme.appendChild(plot);
document.getElementById("container").appendChild(theme);
});
})()</script>
</body>
</html>

View File

@@ -306,50 +306,50 @@
"brightWhite": "#e5e5e5"
},
{
"background": "#000000",
"black": "#000000",
"blue": "#0000AA",
"brightBlack": "#555555",
"brightBlue": "#5555FF",
"brightCyan": "#55FFFF",
"brightGreen": "#55FF55",
"brightPurple": "#FF55FF",
"brightRed": "#FF5555",
"brightWhite": "#FFFFFF",
"brightYellow": "#FFFF55",
"cursorColor": "#00AA00",
"cyan": "#00AAAA",
"foreground": "#AAAAAA",
"green": "#00AA00",
"name": "CGA",
"purple": "#AA00AA",
"red": "#AA0000",
"foreground": "#AAAAAA",
"background": "#000000",
"cursorColor": "#00AA00",
"selectionBackground": "#FFFFFF",
"black": "#000000",
"red": "#AA0000",
"green": "#00AA00",
"yellow": "#AA5500",
"blue": "#0000AA",
"purple": "#AA00AA",
"cyan": "#00AAAA",
"white": "#AAAAAA",
"yellow": "#AA5500"
"brightBlack": "#555555",
"brightRed": "#FF5555",
"brightGreen": "#55FF55",
"brightYellow": "#FFFF55",
"brightBlue": "#5555FF",
"brightPurple": "#FF55FF",
"brightCyan": "#55FFFF",
"brightWhite": "#FFFFFF"
},
{
"background": "#000000",
"black": "#000000",
"blue": "#0000AA",
"brightBlack": "#555555",
"brightBlue": "#5555FF",
"brightCyan": "#55FFFF",
"brightGreen": "#55FF55",
"brightPurple": "#FF55FF",
"brightRed": "#FF5555",
"brightWhite": "#FFFFFF",
"brightYellow": "#FFFF55",
"cursorColor": "#00AA00",
"cyan": "#00AAAA",
"foreground": "#AAAAAA",
"green": "#00AA00",
"name": "IBM 5153",
"purple": "#AA00AA",
"red": "#AA0000",
"foreground": "#AAAAAA",
"background": "#000000",
"cursorColor": "#00AA00",
"selectionBackground": "#FFFFFF",
"black": "#000000",
"red": "#AA0000",
"green": "#00AA00",
"yellow": "#C47E00",
"blue": "#0000AA",
"purple": "#AA00AA",
"cyan": "#00AAAA",
"white": "#AAAAAA",
"yellow": "#C47E00"
"brightBlack": "#555555",
"brightRed": "#FF5555",
"brightGreen": "#55FF55",
"brightYellow": "#FFFF55",
"brightBlue": "#5555FF",
"brightPurple": "#FF55FF",
"brightCyan": "#55FFFF",
"brightWhite": "#FFFFFF"
}
],
"themes": [