mirror of
https://github.com/Vendicated/Vencord.git
synced 2025-02-24 07:25:10 +00:00
more horror
This commit is contained in:
parent
008c8262cb
commit
6e3eb3cc4e
2 changed files with 66 additions and 21 deletions
|
@ -43,7 +43,8 @@ interface OKLAB {
|
||||||
b: number;
|
b: number;
|
||||||
}
|
}
|
||||||
type AnyColor = sRGB | lRGB | HSL | OKLAB;
|
type AnyColor = sRGB | lRGB | HSL | OKLAB;
|
||||||
class Color {
|
const RGB_REGEX = /rgb\((?:(\d+(?:\.\d+)?),? ?)(?:(\d+(?:\.\d+)?),? ?)(?:(\d+(?:\.\d+)?),? ?)\)/;
|
||||||
|
export class Color {
|
||||||
private sRGB: sRGB;
|
private sRGB: sRGB;
|
||||||
private get lRGB(): lRGB {
|
private get lRGB(): lRGB {
|
||||||
return {
|
return {
|
||||||
|
@ -144,14 +145,38 @@ class Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromHex(color: string): Color {
|
public static parse(color: string): Color {
|
||||||
return new Color(Color.hexToRGB(color));
|
{
|
||||||
|
const c = color.replaceAll("#", "");
|
||||||
|
if (c.length === 3 || c.length === 6)
|
||||||
|
return new Color(Color.hexToRGB(color));
|
||||||
|
}
|
||||||
|
rgb: {
|
||||||
|
const c = color.match(RGB_REGEX);
|
||||||
|
if (!c) break rgb;
|
||||||
|
const r = parseFloat(c[1]),
|
||||||
|
g = parseFloat(c[2]),
|
||||||
|
b = parseFloat(c[3]);
|
||||||
|
if (Number.isNaN(r + g + b))
|
||||||
|
throw new Error("invalid rgb value. got: " + color);
|
||||||
|
return new Color({
|
||||||
|
type: "srgb",
|
||||||
|
r: r / 255,
|
||||||
|
g: g / 255,
|
||||||
|
b: b / 255
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw new Error("Color not recognized. got: " + color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static contrast(fg: Color, bg: Color): number {
|
public static contrast(fg: Color, bg: Color): number {
|
||||||
return (fg.lumin + 0.05) / (bg.lumin + 0.05);
|
return (fg.lumin + 0.05) / (bg.lumin + 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static mixokl(c1: string, c2: string, pc1: number): Color {
|
||||||
|
return Color.parse(c1).mix("oklab", pc1 / 100, Color.parse(c2));
|
||||||
|
}
|
||||||
|
|
||||||
public mix(colorspace: "oklab", thisPercent: number, other: Color, otherPercent = 1 - thisPercent): Color {
|
public mix(colorspace: "oklab", thisPercent: number, other: Color, otherPercent = 1 - thisPercent): Color {
|
||||||
switch (colorspace) {
|
switch (colorspace) {
|
||||||
case "oklab": {
|
case "oklab": {
|
||||||
|
@ -212,9 +237,9 @@ class Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HSLtosRGB({ h, s, l }: HSL): sRGB {
|
private static HSLtosRGB({ h, s, l }: HSL): sRGB {
|
||||||
const k = n => (n + h / 30) % 12;
|
const k = (n: number) => (n + h / 30) % 12;
|
||||||
const a = s * Math.min(l, 1 - l);
|
const a = s * Math.min(l, 1 - l);
|
||||||
const f = n => l - a * Math.max(Math.min(k(n) - 3, 9 - k(n), 1), -1);
|
const f = (n: number) => l - a * Math.max(Math.min(k(n) - 3, 9 - k(n), 1), -1);
|
||||||
|
|
||||||
const r = f(0);
|
const r = f(0);
|
||||||
const g = f(8);
|
const g = f(8);
|
||||||
|
@ -250,24 +275,25 @@ class Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Contrast {
|
export class Contrast {
|
||||||
public constructor(private fg: Color, private bg: Color) { }
|
public constructor(private bg: Color) {
|
||||||
|
}
|
||||||
|
|
||||||
private ratio(c: Color) {
|
private ratio(c: Color) {
|
||||||
return Color.contrast(c, this.bg);
|
return Color.contrast(c, this.bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public calculateMinContrastColor(contrast: number, step: number): string {
|
public calculateMinContrastColor(fg: Color, contrast: number, step: number = .01): string {
|
||||||
step = Math.abs(step);
|
step = Math.abs(step);
|
||||||
step = this.bg.lightness > 0.5 ? -step : step;
|
step = this.bg.lightness > 0.5 ? -step : step;
|
||||||
const snapStep = snap.bind(null, step);
|
const snapStep = snap.bind(null, step);
|
||||||
contrast = clampContrast(contrast);
|
contrast = clampContrast(contrast);
|
||||||
contrast = snapStep(contrast);
|
contrast = snapStep(contrast);
|
||||||
const startingContrast = this.ratio(this.fg);
|
const startingContrast = this.ratio(fg);
|
||||||
if (startingContrast >= contrast) return this.fg.rbgString;
|
if (startingContrast >= contrast) return fg.rbgString;
|
||||||
let currentColor: Color = this.fg;
|
let currentColor: Color = fg;
|
||||||
let tries =
|
let tries =
|
||||||
(snapStep(this.bg.lightness) - snapStep(this.fg.lightness)) / step +
|
(snapStep(this.bg.lightness) - snapStep(fg.lightness)) / step +
|
||||||
(Math.abs(.5 - snapStep(this.bg.lightness)) + .5) / Math.abs(step);
|
(Math.abs(.5 - snapStep(this.bg.lightness)) + .5) / Math.abs(step);
|
||||||
while (this.ratio(currentColor) <= contrast && tries--) {
|
while (this.ratio(currentColor) <= contrast && tries--) {
|
||||||
currentColor = currentColor.bumpLightness(step);
|
currentColor = currentColor.bumpLightness(step);
|
||||||
|
|
|
@ -23,8 +23,9 @@ import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { ChannelStore, GuildMemberStore, GuildStore, useEffect } from "@webpack/common";
|
import { ChannelStore, GuildMemberStore, GuildStore, useEffect, useState } from "@webpack/common";
|
||||||
import { useState } from "react";
|
|
||||||
|
import { Color, Contrast } from "./color";
|
||||||
|
|
||||||
|
|
||||||
const useMessageAuthor = findByCodeLazy('"Result cannot be null because the message is not null"');
|
const useMessageAuthor = findByCodeLazy('"Result cannot be null because the message is not null"');
|
||||||
|
@ -234,19 +235,37 @@ export default definePlugin({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
useMessageColorsStyle(message: any, test: any | null) {
|
useMessageColorsStyle(message: any, ref: any | null) {
|
||||||
console.log(test);
|
|
||||||
try {
|
try {
|
||||||
const { messageSaturation } = settings.use(["messageSaturation"]);
|
const { messageSaturation } = settings.use(["messageSaturation"]);
|
||||||
const author = useMessageAuthor(message);
|
const author = useMessageAuthor(message);
|
||||||
|
const contrast = useGetContrastValue();
|
||||||
|
|
||||||
if (author.colorString != null && messageSaturation !== 0 && (!test || parseFloat(settings.store.minColorContrast) === 1)) {
|
if (author.colorString != null && messageSaturation !== 0) {
|
||||||
const value = `color-mix(in oklab, ${author.colorString} ${messageSaturation}%, var({DEFAULT}))`;
|
if (contrast === 1) {
|
||||||
|
const value = `color-mix(in oklab, ${author.colorString} ${messageSaturation}%, var({DEFAULT}))`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
color: value.replace("{DEFAULT}", "--text-normal"),
|
||||||
|
"--header-primary": value.replace("{DEFAULT}", "--header-primary"),
|
||||||
|
"--text-muted": value.replace("{DEFAULT}", "--text-muted")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!ref.current) return;
|
||||||
|
const computed = window.getComputedStyle(ref.current);
|
||||||
|
const textNormal = computed.getPropertyValue("--text-normal"),
|
||||||
|
headerPrimary = computed.getPropertyValue("--header-primary"),
|
||||||
|
textMuted = computed.getPropertyValue("--text-muted");
|
||||||
|
const bgOverlayChat = computed.getPropertyValue("--bg-overlay-chat"),
|
||||||
|
backgroundPrimary = computed.getPropertyValue("--background-primary");
|
||||||
|
if (!(bgOverlayChat || backgroundPrimary)) {
|
||||||
|
throw new Error("No background color found");
|
||||||
|
}
|
||||||
|
const bg = new Contrast(Color.parse(bgOverlayChat || backgroundPrimary));
|
||||||
return {
|
return {
|
||||||
color: value.replace("{DEFAULT}", "--text-normal"),
|
color: bg.calculateMinContrastColor(Color.mixokl(author.colorString, textNormal, messageSaturation), contrast),
|
||||||
"--header-primary": value.replace("{DEFAULT}", "--header-primary"),
|
"--header-primary": bg.calculateMinContrastColor(Color.mixokl(author.colorString, headerPrimary, messageSaturation), contrast),
|
||||||
"--text-muted": value.replace("{DEFAULT}", "--text-muted")
|
"--text-muted": bg.calculateMinContrastColor(Color.mixokl(author.colorString, textMuted, messageSaturation), contrast)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue