2023-07-10 10:14:39 +00:00
|
|
|
import {hashSha256} from "./text.js";
|
|
|
|
|
|
|
|
/** Return a hex color based on a hash of the input string. */
|
|
|
|
export async function getColorFromStringHash(input: string): Promise<string> {
|
|
|
|
const hash = Number.parseInt(await hashSha256(input), 16);
|
|
|
|
const color = Math.abs(hash % 0xff_ff_ff).toString(16);
|
|
|
|
return `#${color}`.padEnd(7, "0");
|
|
|
|
}
|
|
|
|
|
2022-02-23 13:52:06 +00:00
|
|
|
/** Returns whether a hex color is "bright". */
|
2020-10-10 23:32:27 +00:00
|
|
|
export function isColorBright(color: string): boolean {
|
2023-06-23 10:52:03 +00:00
|
|
|
if (color.startsWith("#")) {
|
2020-10-10 23:32:27 +00:00
|
|
|
color = color.slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4 character hex colors have an alpha value, we only need RGB here so remove
|
|
|
|
// the alpha character.
|
|
|
|
if (color.length === 4) {
|
|
|
|
color = color.slice(0, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 8 character hex colors also have an alpha value, so remove the last 2.
|
|
|
|
if (color.length === 8) {
|
|
|
|
color = color.slice(0, 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3 character hex colors can be represented as 6 character ones too, so
|
|
|
|
// transform it. For example "#123" is the same as "#112233".
|
|
|
|
if (color.length === 3) {
|
|
|
|
color = color
|
2023-06-23 10:52:03 +00:00
|
|
|
.split("")
|
2020-10-10 23:32:27 +00:00
|
|
|
.map((value) => value.repeat(2))
|
2023-06-23 10:52:03 +00:00
|
|
|
.join("");
|
2020-10-10 23:32:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Split the color up into 3 segments of 2 characters and convert them from
|
|
|
|
// hexadecimal to decimal.
|
|
|
|
const [red, green, blue] = color
|
|
|
|
.split(/(.{2})/)
|
2023-06-23 10:52:03 +00:00
|
|
|
.filter((value) => value !== "")
|
2020-10-10 23:32:27 +00:00
|
|
|
.map((value) => Number.parseInt(value, 16));
|
|
|
|
|
|
|
|
// Magical numbers taken from https://stackoverflow.com/a/12043228/12251171.
|
|
|
|
// "Per ITU-R BT.709"
|
|
|
|
const brightness = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
|
|
|
|
return brightness > 128;
|
|
|
|
}
|
|
|
|
|
2022-02-23 13:52:06 +00:00
|
|
|
/** CSS custom properties from the Tildes themes. */
|
2020-10-10 23:32:27 +00:00
|
|
|
export const themeColors = [
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Background Primary",
|
|
|
|
value: "--background-primary-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Background Secondary",
|
|
|
|
value: "--background-secondary-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Foreground Primary",
|
|
|
|
value: "--foreground-primary-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Foreground Secondary",
|
|
|
|
value: "--foreground-secondary-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Exemplary",
|
|
|
|
value: "--comment-label-exemplary-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Off-topic",
|
|
|
|
value: "--comment-label-offtopic-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Joke",
|
|
|
|
value: "--comment-label-joke-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Noise",
|
|
|
|
value: "--comment-label-noise-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Malice",
|
|
|
|
value: "--comment-label-malice-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Mine",
|
|
|
|
value: "--stripe-mine-color",
|
2020-10-10 23:32:27 +00:00
|
|
|
},
|
|
|
|
{
|
2023-06-23 10:52:03 +00:00
|
|
|
name: "Official",
|
|
|
|
value: "--alert-color",
|
2022-02-23 13:52:06 +00:00
|
|
|
},
|
2020-10-10 23:32:27 +00:00
|
|
|
];
|