diff options
author | Tor Andersson <tor@ccxvii.net> | 2024-10-29 21:40:25 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-10-29 23:06:03 +0100 |
commit | b81278195d8184e77fe778c325a74aa865562792 (patch) | |
tree | d56eeff66cb7d87fb1857dd7550a03a739e05612 | |
parent | 45802984b67a050844077ee45ecc22458d44311b (diff) | |
download | maria-b81278195d8184e77fe778c325a74aa865562792.tar.gz |
Fully colored power action buttons.
-rw-r--r-- | play.css | 12 | ||||
-rw-r--r-- | play.js | 12 | ||||
-rw-r--r-- | tools/colors.js | 110 | ||||
-rw-r--r-- | tools/gencolors.js | 76 |
4 files changed, 204 insertions, 6 deletions
@@ -46,6 +46,18 @@ body { padding-right: 3px; } +button:has(.austria) { background-color: #ffffff; } +button:has(.bavaria) { background-color: #ffc825; border-color: #fff766 #c69100 #c69100 #fff766; box-shadow: 0 0 0 1px #5c2a00; } +button:has(.bavaria):active:hover { border-color: #c69100 #fff766 #fff766 #c69100; } +button:has(.france) { background-color: #ed1c24; border-color: #ff544d #c00000 #c00000 #ff544d; box-shadow: 0 0 0 1px #680000; } +button:has(.france):active:hover { border-color: #c00000 #ff544d #ff544d #c00000; } +button:has(.pragmatic) { background-color: #5f5c5c; border-color: #7a7777 #454242 #454242 #7a7777; box-shadow: 0 0 0 1px #161313; } +button:has(.pragmatic):active:hover { border-color: #454242 #7a7777 #7a7777 #454242; } +button:has(.prussia) { background-color: #005988; border-color: #2973a4 #00406d #00406d #2973a4; box-shadow: 0 0 0 1px #000f3a; } +button:has(.prussia):active:hover { border-color: #00406d #2973a4 #2973a4 #00406d; } +button:has(.saxony) { background-color: #157d36; border-color: #3e9d54 #005e17 #005e17 #3e9d54; box-shadow: 0 0 0 1px #002500; } +button:has(.saxony):active:hover { border-color: #005e17 #3e9d54 #3e9d54 #005e17; } + .role_marker { display: inline-block; width: 30px; @@ -614,12 +614,12 @@ function make_badge(power) { } const power_image = [ - '<img style="border-radius:50%" height="24" src="images/role_france.2x.png" alt="France">', - '<img style="border-radius:50%" height="24" src="images/role_prussia.2x.png" alt="Prussia">', - '<img style="border-radius:50%" height="24" src="images/role_pragmatic.2x.png" alt="Pragmatic Army">', - '<img style="border-radius:50%" height="24" src="images/role_austria.2x.png" alt="Austria">', - '<img style="border-radius:50%" height="24" src="images/role_bavaria.2x.png" alt="Bavaria">', - '<img style="border-radius:50%" height="24" src="images/role_saxony.2x.png" alt="Saxony">', + '<img class="france" height="24" src="images/role_france.2x.png" alt="France">', + '<img class="prussia" height="24" src="images/role_prussia.2x.png" alt="Prussia">', + '<img class="pragmatic" height="24" src="images/role_pragmatic.2x.png" alt="Pragmatic Army">', + '<img class="austria" height="24" src="images/role_austria.2x.png" alt="Austria">', + '<img class="bavaria" height="24" src="images/role_bavaria.2x.png" alt="Bavaria">', + '<img class="saxony" height="24" src="images/role_saxony.2x.png" alt="Saxony">', ] const power_badge = [ diff --git a/tools/colors.js b/tools/colors.js new file mode 100644 index 0000000..f8f7ace --- /dev/null +++ b/tools/colors.js @@ -0,0 +1,110 @@ +"use strict" + +function rgb_from_any(color) { + switch (color.mode) { + case "rgb": return color + case "lrgb": return rgb_from_lrgb(color) + case "oklab": return rgb_from_oklab(color) + } +} + +function lrgb_from_any(color) { + switch (color.mode) { + case "rgb": return lrgb_from_rgb(color) + case "lrgb": return color + case "oklab": return lrgb_from_oklab(color) + } +} + +function oklab_from_any(color) { + switch (color.mode) { + case "rgb": return oklab_from_rgb(color) + case "lrgb": return oklab_from_lrgb(color) + case "oklab": return color + } +} + +function format_hex(color) { + let {r, g, b} = rgb_from_any(color) + let adj = 1 + r = Math.round(Math.max(0, Math.min(1, r)) * 255) + g = Math.round(Math.max(0, Math.min(1, g)) * 255) + b = Math.round(Math.max(0, Math.min(1, b)) * 255) + let x = (r << 16) | (g << 8) | b + return "#" + x.toString(16).padStart(6, "0") +} + +function parse_hex(str) { + let x = parseInt(str.substring(1), 16) + return { + mode: "rgb", + r: ((x >> 16) & 255) / 255.0, + g: ((x >> 8) & 255) / 255.0, + b: ((x) & 255) / 255.0 + } +} + +function lrgb_from_rgb({ r, g, b }) { + function to_linear(c) { + let ac = Math.abs(c) + if (ac < 0.04045) + return c / 12.92 + return (Math.sign(c) || 1) * Math.pow((ac + 0.055) / 1.055, 2.4) + } + return { + mode: "lrgb", + r: to_linear(r), + g: to_linear(g), + b: to_linear(b) + } +} + +function rgb_from_lrgb({ r, g, b }) { + function from_linear(c) { + let ac = Math.abs(c) + if (ac > 0.0031308) + return (Math.sign(c) || 1) * (1.055 * Math.pow(ac, 1 / 2.4) - 0.055) + return c * 12.92 + } + return { + mode: "rgb", + r: from_linear(r), + g: from_linear(g), + b: from_linear(b) + } +} + +function oklab_from_lrgb({ r, g, b }) { + let L = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b) + let M = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b) + let S = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b) + return { + mode: "oklab", + l: 0.2104542553 * L + 0.793617785 * M - 0.0040720468 * S, + a: 1.9779984951 * L - 2.428592205 * M + 0.4505937099 * S, + b: 0.0259040371 * L + 0.7827717662 * M - 0.808675766 * S + } +} + +function lrgb_from_oklab({ l, a, b }) { + let L = Math.pow(l + 0.3963377774 * a + 0.2158037573 * b, 3) + let M = Math.pow(l - 0.1055613458 * a - 0.0638541728 * b, 3) + let S = Math.pow(l - 0.0894841775 * a - 1.291485548 * b, 3) + return { + mode: "lrgb", + r: +4.0767416621 * L - 3.3077115913 * M + 0.2309699292 * S, + g: -1.2684380046 * L + 2.6097574011 * M - 0.3413193965 * S, + b: -0.0041960863 * L - 0.7034186147 * M + 1.707614701 * S + } +} + +function oklab_from_rgb(rgb) { + return oklab_from_lrgb(lrgb_from_rgb(rgb)) +} + +function rgb_from_oklab(oklab) { + return rgb_from_lrgb(lrgb_from_oklab(oklab)) +} + +if (typeof module === "object") + module.exports = { format_hex, parse_hex, rgb_from_any, lrgb_from_any, oklab_from_any } diff --git a/tools/gencolors.js b/tools/gencolors.js new file mode 100644 index 0000000..63b4bf5 --- /dev/null +++ b/tools/gencolors.js @@ -0,0 +1,76 @@ +const { parse_hex, format_hex, lrgb_from_any, rgb_from_any, oklab_from_any } = require("./colors.js") + +const white = "#ffffff" +const black = "#000000" + +function lerp(a, b, n) { + return a + (b - a) * n +} + +function blend(a, b, n) { + a = lrgb_from_any(parse_hex(a)) + b = lrgb_from_any(parse_hex(b)) + return format_hex({ + mode: "lrgb", + r: lerp(a.r, b.r, n), + g: lerp(a.g, b.g, n), + b: lerp(a.b, b.b, n) + }) +} + +function multiply_luminance(hex, m) { + let oklab = oklab_from_any(parse_hex(hex)) + oklab.l = Math.max(0, Math.min(1, oklab.l * m)) + return format_hex(oklab) +} + +function add_luminance(hex, m) { + let oklab = oklab_from_any(parse_hex(hex)) + oklab.l = Math.max(0, Math.min(1, oklab.l + m)) + return format_hex(oklab) +} + +function make_3d_colors(base) { + return [ + base, + multiply_luminance(base, 0.9), + multiply_luminance(base, 0.8), + multiply_luminance(base, 0.7), + multiply_luminance(base, 0.4) + ] +} + +function make_2d_colors(base) { + return [ + base, + multiply_luminance(base, 1.2), + multiply_luminance(base, 0.8), + multiply_luminance(base, 0.4) + ] +} + +function make_2d_colors_add(base) { + return [ + base, + add_luminance(base, 0.2), + add_luminance(base, -0.2), + add_luminance(base, -0.5), + ] +} + +function print(x) { + console.log(x) +} + +function gencss(color, sel) { + let [ bg, hi, lo, sh ] = make_2d_colors(color) + print(`${sel} { background-color: ${color}; border-color: ${hi} ${lo} ${lo} ${hi}; box-shadow: 0 0 0 1px ${sh}; }`) + print(`${sel}:active:hover { border-color: ${lo} ${hi} ${hi} ${lo}; }`) +} + +gencss("#bbbbbb", "button:has(.austria)") +gencss("#ffc825", "button:has(.bavaria)") +gencss("#ed1c24", "button:has(.france)") +gencss("#5f5c5c", "button:has(.pragmatic)") +gencss("#005988", "button:has(.prussia)") +gencss("#157d36", "button:has(.saxony)") |