diff --git a/src/lib/components/colors/Sliders.svelte b/src/lib/components/colors/Sliders.svelte index 25a6810..7e97070 100644 --- a/src/lib/components/colors/Sliders.svelte +++ b/src/lib/components/colors/Sliders.svelte @@ -95,6 +95,7 @@ style={`--stops: ${alphaGradient}`} value={$color.alpha} oninput={(e) => handleInput(e)} + data-channel="alpha" /> @@ -104,7 +105,17 @@ margin: 0; display: block; appearance: none; - background: linear-gradient(to right, var(--stops)); + background: linear-gradient(to right, var(--stops)), + repeating-linear-gradient( + -45deg, + white 0%, + white 1%, + #ffd0d0 1%, + #ffd0d0 2% + ); + &[data-channel='alpha'] { + background: linear-gradient(to right, var(--stops)); + } } [data-group~='sliders'] { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 148a04a..f2e32a5 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,7 @@ import { clone, display, + inGamut, type PlainColorObject, serialize, set, @@ -32,9 +33,34 @@ export const sliderGradient = ( steps: 10, space: color.space, hue: 'raw', + maxDeltaE: 10, }); + let wasInGamut = false; + const inGamutSteps: string[] = []; + const stepWidth = 100 / (gradientSteps.length - 1); - return gradientSteps.map((c) => display(c)).join(', '); + if (channel === 'alpha') { + return gradientSteps.map((c) => display(c)).join(', '); + } + + gradientSteps.forEach((step, index) => { + if (inGamut(step, 'p3')) { + if (!wasInGamut) { + inGamutSteps.push(`transparent ${stepWidth * (index + 1)}%`); + } + wasInGamut = true; + inGamutSteps.push(`${display(step)} ${stepWidth * index}%`); + } else { + if (wasInGamut) { + inGamutSteps.push(`transparent ${stepWidth * (index - 1)}%`); + } + inGamutSteps.push(`transparent ${stepWidth * index}%`); + + wasInGamut = false; + } + }); + + return inGamutSteps.join(', '); }; function decodeColor(colorHash: string, format: ColorFormatId) {