diff --git a/client/web/src/components/panels/Document.vue b/client/web/src/components/panels/Document.vue index 3751faca3..8bcecb0b4 100644 --- a/client/web/src/components/panels/Document.vue +++ b/client/web/src/components/panels/Document.vue @@ -154,6 +154,7 @@ height: 100%; svg { + background: #ffffff; width: 100%; height: 100%; } @@ -222,10 +223,6 @@ export default defineComponent({ } todo(toolIndex); }, - async updatePrimaryColor(c: { r: number; g: number; b: number; a: number }) { - const { update_primary_color, Color } = await wasm; - update_primary_color(new Color(c.r, c.g, c.b, c.a)); - }, }, mounted() { registerResponseHandler(ResponseType.UpdateCanvas, (responseData: Response) => { @@ -239,9 +236,6 @@ export default defineComponent({ window.addEventListener("keyup", (e: KeyboardEvent) => this.keyUp(e)); window.addEventListener("keydown", (e: KeyboardEvent) => this.keyDown(e)); - - // TODO: Implement an actual UI for chosing colors (this is completely temporary) - this.updatePrimaryColor({ r: 247 / 255, g: 76 / 255, b: 0 / 255, a: 0.6 }); }, data() { return { diff --git a/client/web/src/components/popovers/ColorPicker.vue b/client/web/src/components/popovers/ColorPicker.vue index ccc77098d..1b55a9447 100644 --- a/client/web/src/components/popovers/ColorPicker.vue +++ b/client/web/src/components/popovers/ColorPicker.vue @@ -1,30 +1,31 @@ diff --git a/client/web/src/lib/utils.ts b/client/web/src/lib/utils.ts new file mode 100644 index 000000000..3054c932a --- /dev/null +++ b/client/web/src/lib/utils.ts @@ -0,0 +1,83 @@ +export interface RGB { + r: number; + g: number; + b: number; + a: number; +} + +export interface HSV { + h: number; + s: number; + v: number; + a: number; +} + +export function hsvToRgb(hsv: HSV): RGB { + let { h } = hsv; + const { s, v } = hsv; + h *= 6; + const i = Math.floor(h); + const f = h - i; + const p = v * (1 - s); + const q = v * (1 - f * s); + const t = v * (1 - (1 - f) * s); + const mod = i % 6; + const r = Math.round([v, q, p, p, t, v][mod]); + const g = Math.round([t, v, v, q, p, p][mod]); + const b = Math.round([p, p, t, v, v, q][mod]); + return { r, g, b, a: hsv.a }; +} + +export function rgbToHsv(rgb: RGB) { + const { r, g, b } = rgb; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const d = max - min; + const s = max === 0 ? 0 : d / max; + const v = max; + let h = 0; + if (max === min) { + h = 0; + } else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + default: + } + h /= 6; + } + return { h, s, v, a: rgb.a }; +} + +export function rgbToDecimalRgb(rgb: RGB) { + const r = rgb.r / 255; + const g = rgb.g / 255; + const b = rgb.b / 255; + return { r, g, b, a: rgb.a }; +} + +export function clamp(value: number, min = 0, max = 1) { + return Math.max(min, Math.min(value, max)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function isRGB(data: any): data is RGB { + if (typeof data !== "object" || data === null) return false; + return ( + typeof data.r === "number" && + !Number.isNaN(data.r) && + typeof data.g === "number" && + !Number.isNaN(data.g) && + typeof data.b === "number" && + !Number.isNaN(data.b) && + typeof data.a === "number" && + !Number.isNaN(data.a) + ); +}