mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 00:28:12 +08:00
Clean up Gradient and Color classes in TS by removing their methods (#3857)
This commit is contained in:
@@ -2,7 +2,25 @@
|
||||
import { getContext, onDestroy, createEventDispatcher, tick } from "svelte";
|
||||
|
||||
import type { HSV, RGB, FillChoice, MenuDirection } from "@graphite/messages";
|
||||
import { Color, contrastingOutlineFactor, Gradient } from "@graphite/messages";
|
||||
import {
|
||||
type Color,
|
||||
contrastingOutlineFactor,
|
||||
isColor,
|
||||
isGradient,
|
||||
createColor,
|
||||
createNoneColor,
|
||||
createColorFromHSVA,
|
||||
colorFromCSS,
|
||||
colorToRgb255,
|
||||
colorToHSVA,
|
||||
colorToHexOptionalAlpha,
|
||||
colorToHexNoAlpha,
|
||||
colorToRgbCSS,
|
||||
colorContrastingColor,
|
||||
colorOpaque,
|
||||
colorEquals,
|
||||
gradientFirstColor,
|
||||
} from "@graphite/messages";
|
||||
import type { TooltipState } from "@graphite/state-providers/tooltip";
|
||||
import { clamp } from "@graphite/utility-functions/math";
|
||||
import { isDesktop } from "@graphite/utility-functions/platform";
|
||||
@@ -51,16 +69,17 @@
|
||||
// TODO: See if this should be made to follow the pattern of DropdownInput.svelte so this could be removed
|
||||
export let open: boolean;
|
||||
|
||||
const hsvaOrNone = colorOrGradient instanceof Color ? colorOrGradient.toHSVA() : colorOrGradient.firstColor()?.toHSVA();
|
||||
const colorForHSVA = isColor(colorOrGradient) ? colorOrGradient : gradientFirstColor(colorOrGradient);
|
||||
const hsvaOrNone = colorForHSVA ? colorToHSVA(colorForHSVA) : undefined;
|
||||
const hsva = hsvaOrNone || { h: 0, s: 0, v: 0, a: 1 };
|
||||
|
||||
// Gradient color stops
|
||||
$: gradient = colorOrGradient instanceof Gradient ? colorOrGradient : undefined;
|
||||
$: gradient = isGradient(colorOrGradient) ? colorOrGradient : undefined;
|
||||
let activeIndex = 0 as number | undefined;
|
||||
let activeIndexIsMidpoint = false;
|
||||
$: selectedGradientColor = (activeIndex !== undefined && gradient?.color[activeIndex]) || (Color.fromCSS("black") as Color);
|
||||
$: selectedGradientColor = (activeIndex !== undefined && gradient?.color[activeIndex]) || (colorFromCSS("black") as Color);
|
||||
// Currently viewed color
|
||||
$: color = colorOrGradient instanceof Color ? colorOrGradient : selectedGradientColor;
|
||||
$: color = isColor(colorOrGradient) ? colorOrGradient : selectedGradientColor;
|
||||
// New color components
|
||||
let hue = hsva.h;
|
||||
let saturation = hsva.s;
|
||||
@@ -97,16 +116,16 @@
|
||||
|
||||
$: oldColor = generateColor(oldHue, oldSaturation, oldValue, oldAlpha, oldIsNone);
|
||||
$: newColor = generateColor(hue, saturation, value, alpha, isNone);
|
||||
$: rgbChannels = Object.entries(newColor.toRgb255() || { r: undefined, g: undefined, b: undefined }) as [keyof RGB, number | undefined][];
|
||||
$: rgbChannels = Object.entries(colorToRgb255(newColor) || { r: undefined, g: undefined, b: undefined }) as [keyof RGB, number | undefined][];
|
||||
$: hsvChannels = Object.entries(!isNone ? { h: hue * 360, s: saturation * 100, v: value * 100 } : { h: undefined, s: undefined, v: undefined }) as [keyof HSV, number | undefined][];
|
||||
$: opaqueHueColor = new Color({ h: hue, s: 1, v: 1, a: 1 });
|
||||
$: opaqueHueColor = createColorFromHSVA(hue, 1, 1, 1);
|
||||
$: outlineFactor = Math.max(contrastingOutlineFactor(newColor, "--color-2-mildblack", 0.01), contrastingOutlineFactor(oldColor, "--color-2-mildblack", 0.01));
|
||||
$: outlined = outlineFactor > 0.0001;
|
||||
$: transparency = newColor.alpha < 1 || oldColor.alpha < 1;
|
||||
|
||||
function generateColor(h: number, s: number, v: number, a: number, none: boolean) {
|
||||
if (none) return new Color("none");
|
||||
return new Color({ h, s, v, a });
|
||||
if (none) return createNoneColor();
|
||||
return createColorFromHSVA(h, s, v, a);
|
||||
}
|
||||
|
||||
async function watchOpen(open: boolean) {
|
||||
@@ -119,7 +138,7 @@
|
||||
}
|
||||
|
||||
function watchColor(color: Color) {
|
||||
const hsva = color.toHSVA();
|
||||
const hsva = colorToHSVA(color);
|
||||
|
||||
if (hsva === undefined) {
|
||||
setNewHSVA(0, 0, 0, 1, true);
|
||||
@@ -185,7 +204,7 @@
|
||||
strayCloses = false;
|
||||
}
|
||||
|
||||
const color = new Color({ h: hue, s: saturation, v: value, a: alpha });
|
||||
const color = createColorFromHSVA(hue, saturation, value, alpha);
|
||||
setColor(color);
|
||||
|
||||
if (!e.shiftKey) {
|
||||
@@ -226,7 +245,7 @@
|
||||
saturation = saturationRestoreWhenShiftReleased;
|
||||
value = valueRestoreWhenShiftReleased;
|
||||
|
||||
const color = new Color({ h: hue, s: saturation, v: value, a: alpha });
|
||||
const color = createColorFromHSVA(hue, saturation, value, alpha);
|
||||
setColor(color);
|
||||
}
|
||||
}
|
||||
@@ -282,14 +301,14 @@
|
||||
value = valueBeforeDrag;
|
||||
alpha = alphaBeforeDrag;
|
||||
|
||||
const color = new Color({ h: hue, s: saturation, v: value, a: alpha });
|
||||
const color = createColorFromHSVA(hue, saturation, value, alpha);
|
||||
setColor(color);
|
||||
}
|
||||
|
||||
function setColor(color?: Color) {
|
||||
const colorToEmit = color || new Color({ h: hue, s: saturation, v: value, a: alpha });
|
||||
const colorToEmit = color || createColorFromHSVA(hue, saturation, value, alpha);
|
||||
|
||||
if (gradientSpectrumInputWidget && activeIndex !== undefined && gradient?.position[activeIndex] !== undefined && colorOrGradient instanceof Gradient) {
|
||||
if (gradientSpectrumInputWidget && activeIndex !== undefined && gradient?.position[activeIndex] !== undefined && isGradient(colorOrGradient)) {
|
||||
colorOrGradient.color[activeIndex] = colorToEmit;
|
||||
}
|
||||
|
||||
@@ -312,7 +331,7 @@
|
||||
}
|
||||
|
||||
function setColorCode(colorCode: string) {
|
||||
const color = Color.fromCSS(colorCode);
|
||||
const color = colorFromCSS(colorCode);
|
||||
if (color) setColor(color);
|
||||
}
|
||||
|
||||
@@ -320,9 +339,9 @@
|
||||
// Do nothing if the given value is undefined
|
||||
if (strength === undefined) return undefined;
|
||||
// Set the specified channel to the given value
|
||||
else if (channel === "r") setColor(new Color(strength / 255, newColor.green, newColor.blue, newColor.alpha));
|
||||
else if (channel === "g") setColor(new Color(newColor.red, strength / 255, newColor.blue, newColor.alpha));
|
||||
else if (channel === "b") setColor(new Color(newColor.red, newColor.green, strength / 255, newColor.alpha));
|
||||
else if (channel === "r") setColor(createColor(strength / 255, newColor.green, newColor.blue, newColor.alpha));
|
||||
else if (channel === "g") setColor(createColor(newColor.red, strength / 255, newColor.blue, newColor.alpha));
|
||||
else if (channel === "b") setColor(createColor(newColor.red, newColor.green, strength / 255, newColor.alpha));
|
||||
}
|
||||
|
||||
function setColorHSV(channel: keyof HSV, strength: number | undefined) {
|
||||
@@ -353,10 +372,10 @@
|
||||
|
||||
if (preset === "none") {
|
||||
setNewHSVA(0, 0, 0, 1, true);
|
||||
setColor(new Color("none"));
|
||||
setColor(createNoneColor());
|
||||
} else {
|
||||
const presetColor = new Color(...PURE_COLORS[preset], 1);
|
||||
const hsva = presetColor.toHSVA() || { h: 0, s: 0, v: 0, a: 0 };
|
||||
const presetColor = createColor(...PURE_COLORS[preset], 1);
|
||||
const hsva = colorToHSVA(presetColor) || { h: 0, s: 0, v: 0, a: 0 };
|
||||
|
||||
setNewHSVA(hsva.h, hsva.s, hsva.v, hsva.a, false);
|
||||
setColor(presetColor);
|
||||
@@ -406,7 +425,7 @@
|
||||
activeIndexIsMidpoint = activeMarkerIsMidpoint;
|
||||
|
||||
const color = activeMarkerIndex === undefined ? undefined : gradient?.color[activeMarkerIndex];
|
||||
const hsva = color?.toHSVA();
|
||||
const hsva = color ? colorToHSVA(color) : undefined;
|
||||
if (!color || !hsva) return;
|
||||
|
||||
setColor(color);
|
||||
@@ -427,14 +446,14 @@
|
||||
<FloatingMenu class="color-picker" classes={{ disabled }} {open} on:open {strayCloses} escapeCloses={strayCloses && !gradientSpectrumDragging} {direction} type="Popover" bind:this={self}>
|
||||
<LayoutRow
|
||||
styles={{
|
||||
"--new-color": newColor.toHexOptionalAlpha(),
|
||||
"--new-color-contrasting": newColor.contrastingColor(),
|
||||
"--old-color": oldColor.toHexOptionalAlpha(),
|
||||
"--old-color-contrasting": oldColor.contrastingColor(),
|
||||
"--hue-color": opaqueHueColor.toRgbCSS(),
|
||||
"--hue-color-contrasting": opaqueHueColor.contrastingColor(),
|
||||
"--opaque-color": (newColor.opaque() || new Color(0, 0, 0, 1)).toHexNoAlpha(),
|
||||
"--opaque-color-contrasting": (newColor.opaque() || new Color(0, 0, 0, 1)).contrastingColor(),
|
||||
"--new-color": colorToHexOptionalAlpha(newColor),
|
||||
"--new-color-contrasting": colorContrastingColor(newColor),
|
||||
"--old-color": colorToHexOptionalAlpha(oldColor),
|
||||
"--old-color-contrasting": colorContrastingColor(oldColor),
|
||||
"--hue-color": colorToRgbCSS(opaqueHueColor),
|
||||
"--hue-color-contrasting": colorContrastingColor(opaqueHueColor),
|
||||
"--opaque-color": colorToHexNoAlpha(colorOpaque(newColor) || createColor(0, 0, 0, 1)),
|
||||
"--opaque-color-contrasting": colorContrastingColor(colorOpaque(newColor) || createColor(0, 0, 0, 1)),
|
||||
}}
|
||||
>
|
||||
{@const hueDescription = "The shade along the spectrum of the rainbow."}
|
||||
@@ -528,18 +547,18 @@
|
||||
class="choice-preview"
|
||||
classes={{ outlined, transparency }}
|
||||
styles={{ "--outline-amount": outlineFactor }}
|
||||
tooltipDescription={!newColor.equals(oldColor) ? "Comparison between the present color choice (left) and the color before it was changed (right)." : "The present color choice."}
|
||||
tooltipDescription={!colorEquals(newColor, oldColor) ? "Comparison between the present color choice (left) and the color before it was changed (right)." : "The present color choice."}
|
||||
>
|
||||
{#if !newColor.equals(oldColor) && !disabled}
|
||||
{#if !colorEquals(newColor, oldColor) && !disabled}
|
||||
<div class="swap-button-background"></div>
|
||||
<IconButton class="swap-button" icon="SwapHorizontal" size={16} action={swapNewWithOld} tooltipLabel="Swap" />
|
||||
{/if}
|
||||
<LayoutCol class="new-color" classes={{ none: isNone }}>
|
||||
{#if !newColor.equals(oldColor)}
|
||||
{#if !colorEquals(newColor, oldColor)}
|
||||
<TextLabel>New</TextLabel>
|
||||
{/if}
|
||||
</LayoutCol>
|
||||
{#if !newColor.equals(oldColor)}
|
||||
{#if !colorEquals(newColor, oldColor)}
|
||||
<LayoutCol class="old-color" classes={{ none: oldIsNone }}>
|
||||
<TextLabel>Old</TextLabel>
|
||||
</LayoutCol>
|
||||
@@ -552,7 +571,7 @@
|
||||
<Separator style="Related" />
|
||||
<LayoutRow>
|
||||
<TextInput
|
||||
value={newColor.toHexOptionalAlpha() || "-"}
|
||||
value={colorToHexOptionalAlpha(newColor) || "-"}
|
||||
{disabled}
|
||||
on:commitText={({ detail }) => {
|
||||
dispatch("startHistoryTransaction");
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
type MenuDirection,
|
||||
type MouseCursorIcon,
|
||||
type XY,
|
||||
Color,
|
||||
type Color,
|
||||
isColor,
|
||||
createColor,
|
||||
colorToHexOptionalAlpha,
|
||||
DisplayEditableTextbox,
|
||||
DisplayEditableTextboxUpdateFontData,
|
||||
DisplayEditableTextboxTransform,
|
||||
@@ -360,7 +363,7 @@
|
||||
textInput.style.height = height;
|
||||
textInput.style.lineHeight = `${data.lineHeightRatio}`;
|
||||
textInput.style.fontSize = `${data.fontSize}px`;
|
||||
textInput.style.color = data.color.toHexOptionalAlpha() || "transparent";
|
||||
textInput.style.color = colorToHexOptionalAlpha(data.color) || "transparent";
|
||||
textInput.style.textAlign = data.align;
|
||||
|
||||
textInput.oninput = () => {
|
||||
@@ -609,9 +612,9 @@
|
||||
gradientStopPickerColor = undefined;
|
||||
}
|
||||
}}
|
||||
colorOrGradient={gradientStopPickerColor || new Color()}
|
||||
colorOrGradient={gradientStopPickerColor || createColor(0, 0, 0, 1)}
|
||||
on:colorOrGradient={({ detail }) => {
|
||||
if (detail instanceof Color) {
|
||||
if (isColor(detail)) {
|
||||
editor.handle.updateGradientStopColor(detail.red, detail.green, detail.blue, detail.alpha);
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
import type { FillChoice, MenuDirection, ActionShortcut } from "@graphite/messages";
|
||||
import { Color, contrastingOutlineFactor, Gradient } from "@graphite/messages";
|
||||
import { type Color, contrastingOutlineFactor, isColor, isGradient, colorToHexOptionalAlpha, gradientToLinearGradientCSS } from "@graphite/messages";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
$: outlineFactor = contrastingOutlineFactor(value, ["--color-1-nearblack", "--color-3-darkgray"], 0.01);
|
||||
$: outlined = outlineFactor > 0.0001;
|
||||
$: chosenGradient = value instanceof Gradient ? value.toLinearGradientCSS() : `linear-gradient(${value.toHexOptionalAlpha()}, ${value.toHexOptionalAlpha()})`;
|
||||
$: none = value instanceof Color ? value.none : false;
|
||||
$: transparency = value instanceof Gradient ? value.color.some((color) => color.alpha < 1) : value.alpha < 1;
|
||||
$: chosenGradient = isGradient(value) ? gradientToLinearGradientCSS(value) : `linear-gradient(${colorToHexOptionalAlpha(value)}, ${colorToHexOptionalAlpha(value)})`;
|
||||
$: none = isColor(value) ? value.none : false;
|
||||
$: transparency = isGradient(value) ? value.color.some((color: Color) => color.alpha < 1) : value.alpha < 1;
|
||||
</script>
|
||||
|
||||
<LayoutCol class="color-button" classes={{ open, disabled, narrow, none, transparency, outlined, "direction-top": menuDirection === "Top" }} {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { createEventDispatcher, onDestroy } from "svelte";
|
||||
|
||||
import { evaluateGradientAtPosition } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { Color, type Gradient } from "@graphite/messages";
|
||||
import { type Color, type Gradient, createColor, colorToHexOptionalAlpha, colorToRgbCSS, gradientFirstColor, gradientLastColor, gradientToLinearGradientCSS } from "@graphite/messages";
|
||||
|
||||
import { preventEscapeClosingParentFloatingMenu } from "@graphite/components/layout/FloatingMenu.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
@@ -115,7 +115,7 @@
|
||||
// Determine the color of the new stop by evaluating the gradient at the position of the new stop
|
||||
type ReturnedColor = { red: number; green: number; blue: number; alpha: number };
|
||||
const evaluated = evaluateGradientAtPosition(position, new Float64Array(gradient.position), new Float64Array(gradient.midpoint), gradient.color) as ReturnedColor;
|
||||
const color = new Color(evaluated.red, evaluated.green, evaluated.blue, evaluated.alpha);
|
||||
const color = createColor(evaluated.red, evaluated.green, evaluated.blue, evaluated.alpha);
|
||||
|
||||
// Insert the new stop into the gradient
|
||||
gradient.position.splice(index, 0, position);
|
||||
@@ -368,9 +368,9 @@
|
||||
class="spectrum-input"
|
||||
classes={{ disabled }}
|
||||
styles={{
|
||||
"--gradient-start": gradient.firstColor()?.toHexOptionalAlpha() || "black",
|
||||
"--gradient-end": gradient.lastColor()?.toHexOptionalAlpha() || "black",
|
||||
"--gradient-stops": gradient.toLinearGradientCSS(),
|
||||
"--gradient-start": ((color) => (color ? colorToHexOptionalAlpha(color) : "black"))(gradientFirstColor(gradient)),
|
||||
"--gradient-end": ((color) => (color ? colorToHexOptionalAlpha(color) : "black"))(gradientLastColor(gradient)),
|
||||
"--gradient-stops": gradientToLinearGradientCSS(gradient),
|
||||
}}
|
||||
>
|
||||
<LayoutRow class="gradient-strip" on:pointerdown={insertStop}></LayoutRow>
|
||||
@@ -396,7 +396,7 @@
|
||||
class="marker"
|
||||
class:active={index === activeMarkerIndex && !activeMarkerIsMidpoint}
|
||||
style:--marker-position={marker.position}
|
||||
style:--marker-color={marker.color.toRgbCSS()}
|
||||
style:--marker-color={colorToRgbCSS(marker.color)}
|
||||
on:pointerdown={(e) => markerPointerDown(e, index)}
|
||||
data-gradient-marker
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { Color } from "@graphite/messages";
|
||||
import { type Color, isColor, colorToRgbaCSS } from "@graphite/messages";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
@@ -38,22 +38,22 @@
|
||||
|
||||
<LayoutCol class="working-colors-button">
|
||||
<LayoutRow class="primary swatch">
|
||||
<button on:click={clickPrimarySwatch} class:open={primaryOpen} style:--swatch-color={primary.toRgbaCSS()} data-floating-menu-spawner data-block-hover-transfer tabindex="0"></button>
|
||||
<button on:click={clickPrimarySwatch} class:open={primaryOpen} style:--swatch-color={colorToRgbaCSS(primary)} data-floating-menu-spawner data-block-hover-transfer tabindex="0"></button>
|
||||
<ColorPicker
|
||||
open={primaryOpen}
|
||||
on:open={({ detail }) => (primaryOpen = detail)}
|
||||
colorOrGradient={primary}
|
||||
on:colorOrGradient={({ detail }) => detail instanceof Color && primaryColorChanged(detail)}
|
||||
on:colorOrGradient={({ detail }) => isColor(detail) && primaryColorChanged(detail)}
|
||||
direction="Right"
|
||||
/>
|
||||
</LayoutRow>
|
||||
<LayoutRow class="secondary swatch">
|
||||
<button on:click={clickSecondarySwatch} class:open={secondaryOpen} style:--swatch-color={secondary.toRgbaCSS()} data-floating-menu-spawner data-block-hover-transfer tabindex="0"></button>
|
||||
<button on:click={clickSecondarySwatch} class:open={secondaryOpen} style:--swatch-color={colorToRgbaCSS(secondary)} data-floating-menu-spawner data-block-hover-transfer tabindex="0"></button>
|
||||
<ColorPicker
|
||||
open={secondaryOpen}
|
||||
on:open={({ detail }) => (secondaryOpen = detail)}
|
||||
colorOrGradient={secondary}
|
||||
on:colorOrGradient={({ detail }) => detail instanceof Color && secondaryColorChanged(detail)}
|
||||
on:colorOrGradient={({ detail }) => isColor(detail) && secondaryColorChanged(detail)}
|
||||
direction="Right"
|
||||
/>
|
||||
</LayoutRow>
|
||||
|
||||
Reference in New Issue
Block a user