From 92749d67612ff30c8e1c0aad5eb0152b02dcc722 Mon Sep 17 00:00:00 2001 From: eliza Date: Tue, 6 Feb 2024 19:22:38 -0800 Subject: [PATCH 1/6] fix(color-picker): alpha-channel slider scope updates --- .../components/color-picker/color-picker.tsx | 46 ++++++++++++++++--- .../src/components/color-picker/interfaces.ts | 2 + 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index 5a267902bf0..82a5231797c 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -13,7 +13,16 @@ import { } from "@stencil/core"; import Color from "color"; -import { Channels, ColorMode, ColorValue, HSLA, HSVA, InternalColor, RGBA } from "./interfaces"; +import { + Channels, + ColorMode, + ColorValue, + HSLA, + HSVA, + InternalColor, + RGBA, + SliderType, +} from "./interfaces"; import { throttle } from "lodash-es"; import { Direction, getElementDir, isPrimaryPointerButton } from "../../utils/dom"; import { Scale } from "../interfaces"; @@ -1102,7 +1111,6 @@ export class ColorPicker }, } = this; const hue = (HUE_LIMIT_CONSTRAINED / width) * x; - this.internalColorSet(this.baseColorFieldColor.hue(hue), false); } @@ -1113,7 +1121,6 @@ export class ColorPicker }, } = this; const alpha = opacityToAlpha((OPACITY_LIMITS.max / width) * x); - this.internalColorSet(this.baseColorFieldColor.alpha(alpha), false); } @@ -1376,13 +1383,14 @@ export class ColorPicker const x = hsvColor.saturationv() / (HSV_LIMITS.s / width); const y = height - hsvColor.value() / (HSV_LIMITS.v / height); + const sliderType = "colorField"; requestAnimationFrame(() => { this.colorFieldScopeLeft = x; this.colorFieldScopeTop = y; }); - this.drawThumb(this.colorFieldRenderingContext, radius, x, y, hsvColor); + this.drawThumb(this.colorFieldRenderingContext, radius, x, y, hsvColor, sliderType); } private drawThumb( @@ -1391,6 +1399,7 @@ export class ColorPicker x: number, y: number, color: Color, + sliderType: SliderType, ): void { const startAngle = 0; const endAngle = 2 * Math.PI; @@ -1400,14 +1409,28 @@ export class ColorPicker context.arc(x, y, radius, startAngle, endAngle); context.fillStyle = "#fff"; context.fill(); + context.strokeStyle = "rgba(0,0,0,0.3)"; context.lineWidth = outlineWidth; context.stroke(); + const pattern = context.createPattern(this.getCheckeredBackgroundPattern(), "repeat"); + + context.beginPath(); + context.arc(x, y, radius - 3, startAngle, endAngle); + context.fillStyle = pattern; + context.fill(); + + context.globalCompositeOperation = "source-atop"; + context.beginPath(); context.arc(x, y, radius - 3, startAngle, endAngle); - context.fillStyle = color.rgb().alpha(1).string(); + sliderType === "opacity" + ? (context.fillStyle = color.rgb().alpha(color.alpha()).string()) + : (context.fillStyle = color.rgb().alpha(1).string()); context.fill(); + + context.globalCompositeOperation = "source-over"; } private drawActiveHueSliderColor(): void { @@ -1429,12 +1452,13 @@ export class ColorPicker const x = hsvColor.hue() / (HUE_LIMIT_CONSTRAINED / width); const y = radius; const sliderBoundX = this.getSliderBoundX(x, width, radius); + const sliderType = "hue"; requestAnimationFrame(() => { this.hueScopeLeft = sliderBoundX; }); - this.drawThumb(this.hueSliderRenderingContext, radius, sliderBoundX, y, hsvColor); + this.drawThumb(this.hueSliderRenderingContext, radius, sliderBoundX, y, hsvColor, sliderType); } private drawHueSlider(): void { @@ -1584,12 +1608,20 @@ export class ColorPicker const x = alphaToOpacity(hsvColor.alpha()) / (OPACITY_LIMITS.max / width); const y = radius; const sliderBoundX = this.getSliderBoundX(x, width, radius); + const sliderType = "opacity"; requestAnimationFrame(() => { this.opacityScopeLeft = sliderBoundX; }); - this.drawThumb(this.opacitySliderRenderingContext, radius, sliderBoundX, y, hsvColor); + this.drawThumb( + this.opacitySliderRenderingContext, + radius, + sliderBoundX, + y, + hsvColor, + sliderType, + ); } private getSliderBoundX(x: number, width: number, radius: number): number { diff --git a/packages/calcite-components/src/components/color-picker/interfaces.ts b/packages/calcite-components/src/components/color-picker/interfaces.ts index e0ec1e689c1..8df6b61c673 100644 --- a/packages/calcite-components/src/components/color-picker/interfaces.ts +++ b/packages/calcite-components/src/components/color-picker/interfaces.ts @@ -2,6 +2,8 @@ import type Color from "color"; export type ColorMode = "rgb" | "hsv"; +export type SliderType = "colorField" | "hue" | "opacity"; + export type Channels = [number, number, number, number]; // need to do this otherwise, stencil build doesn't pick up the type import From c98fbfeffa04c977e49b620d7c0de25b2080d540 Mon Sep 17 00:00:00 2001 From: eliza Date: Tue, 6 Feb 2024 19:27:03 -0800 Subject: [PATCH 2/6] cleanup --- .../src/components/color-picker/color-picker.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index 82a5231797c..0e34d2c3ab3 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -1111,6 +1111,7 @@ export class ColorPicker }, } = this; const hue = (HUE_LIMIT_CONSTRAINED / width) * x; + this.internalColorSet(this.baseColorFieldColor.hue(hue), false); } @@ -1121,6 +1122,7 @@ export class ColorPicker }, } = this; const alpha = opacityToAlpha((OPACITY_LIMITS.max / width) * x); + this.internalColorSet(this.baseColorFieldColor.alpha(alpha), false); } From d76bf680945ca1108e619b4539904feb610aea93 Mon Sep 17 00:00:00 2001 From: eliza Date: Wed, 7 Feb 2024 15:38:59 -0800 Subject: [PATCH 3/6] replace sliderType argument with boolean applyAlpha, only apply checkered pattern if color.alpha() < 1 --- .../components/color-picker/color-picker.tsx | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index 0e34d2c3ab3..9c2d18a8437 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -13,16 +13,7 @@ import { } from "@stencil/core"; import Color from "color"; -import { - Channels, - ColorMode, - ColorValue, - HSLA, - HSVA, - InternalColor, - RGBA, - SliderType, -} from "./interfaces"; +import { Channels, ColorMode, ColorValue, HSLA, HSVA, InternalColor, RGBA } from "./interfaces"; import { throttle } from "lodash-es"; import { Direction, getElementDir, isPrimaryPointerButton } from "../../utils/dom"; import { Scale } from "../interfaces"; @@ -1385,14 +1376,13 @@ export class ColorPicker const x = hsvColor.saturationv() / (HSV_LIMITS.s / width); const y = height - hsvColor.value() / (HSV_LIMITS.v / height); - const sliderType = "colorField"; requestAnimationFrame(() => { this.colorFieldScopeLeft = x; this.colorFieldScopeTop = y; }); - this.drawThumb(this.colorFieldRenderingContext, radius, x, y, hsvColor, sliderType); + this.drawThumb(this.colorFieldRenderingContext, radius, x, y, hsvColor, false); } private drawThumb( @@ -1401,7 +1391,7 @@ export class ColorPicker x: number, y: number, color: Color, - sliderType: SliderType, + applyAlpha: boolean, ): void { const startAngle = 0; const endAngle = 2 * Math.PI; @@ -1418,16 +1408,18 @@ export class ColorPicker const pattern = context.createPattern(this.getCheckeredBackgroundPattern(), "repeat"); - context.beginPath(); - context.arc(x, y, radius - 3, startAngle, endAngle); - context.fillStyle = pattern; - context.fill(); + if (color.alpha() < 1) { + context.beginPath(); + context.arc(x, y, radius - 3, startAngle, endAngle); + context.fillStyle = pattern; + context.fill(); + } context.globalCompositeOperation = "source-atop"; context.beginPath(); context.arc(x, y, radius - 3, startAngle, endAngle); - sliderType === "opacity" + applyAlpha ? (context.fillStyle = color.rgb().alpha(color.alpha()).string()) : (context.fillStyle = color.rgb().alpha(1).string()); context.fill(); @@ -1454,13 +1446,12 @@ export class ColorPicker const x = hsvColor.hue() / (HUE_LIMIT_CONSTRAINED / width); const y = radius; const sliderBoundX = this.getSliderBoundX(x, width, radius); - const sliderType = "hue"; requestAnimationFrame(() => { this.hueScopeLeft = sliderBoundX; }); - this.drawThumb(this.hueSliderRenderingContext, radius, sliderBoundX, y, hsvColor, sliderType); + this.drawThumb(this.hueSliderRenderingContext, radius, sliderBoundX, y, hsvColor, false); } private drawHueSlider(): void { @@ -1610,20 +1601,12 @@ export class ColorPicker const x = alphaToOpacity(hsvColor.alpha()) / (OPACITY_LIMITS.max / width); const y = radius; const sliderBoundX = this.getSliderBoundX(x, width, radius); - const sliderType = "opacity"; requestAnimationFrame(() => { this.opacityScopeLeft = sliderBoundX; }); - this.drawThumb( - this.opacitySliderRenderingContext, - radius, - sliderBoundX, - y, - hsvColor, - sliderType, - ); + this.drawThumb(this.opacitySliderRenderingContext, radius, sliderBoundX, y, hsvColor, true); } private getSliderBoundX(x: number, width: number, radius: number): number { From fb37c291a154788aa89bf026dd322c738bab5bf5 Mon Sep 17 00:00:00 2001 From: eliza Date: Wed, 7 Feb 2024 15:46:43 -0800 Subject: [PATCH 4/6] remove SliderType from interfaces --- .../src/components/color-picker/interfaces.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/calcite-components/src/components/color-picker/interfaces.ts b/packages/calcite-components/src/components/color-picker/interfaces.ts index 8df6b61c673..e0ec1e689c1 100644 --- a/packages/calcite-components/src/components/color-picker/interfaces.ts +++ b/packages/calcite-components/src/components/color-picker/interfaces.ts @@ -2,8 +2,6 @@ import type Color from "color"; export type ColorMode = "rgb" | "hsv"; -export type SliderType = "colorField" | "hue" | "opacity"; - export type Channels = [number, number, number, number]; // need to do this otherwise, stencil build doesn't pick up the type import From 2a5b1b81568c6191ca7817bc91ea55b1db2c536f Mon Sep 17 00:00:00 2001 From: eliza Date: Wed, 7 Feb 2024 16:50:11 -0800 Subject: [PATCH 5/6] refactor and simplify --- .../src/components/color-picker/color-picker.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index 9c2d18a8437..125a9c4def7 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -1408,7 +1408,7 @@ export class ColorPicker const pattern = context.createPattern(this.getCheckeredBackgroundPattern(), "repeat"); - if (color.alpha() < 1) { + if (color.alpha() < 1 && applyAlpha) { context.beginPath(); context.arc(x, y, radius - 3, startAngle, endAngle); context.fillStyle = pattern; @@ -1419,9 +1419,8 @@ export class ColorPicker context.beginPath(); context.arc(x, y, radius - 3, startAngle, endAngle); - applyAlpha - ? (context.fillStyle = color.rgb().alpha(color.alpha()).string()) - : (context.fillStyle = color.rgb().alpha(1).string()); + const alpha = applyAlpha ? color.alpha() : 1; + context.fillStyle = color.rgb().alpha(alpha).string(); context.fill(); context.globalCompositeOperation = "source-over"; From a7245a0480fdf59e70960b2714b8adbf8ff20717 Mon Sep 17 00:00:00 2001 From: eliza Date: Thu, 8 Feb 2024 13:26:49 -0800 Subject: [PATCH 6/6] clean up --- .../src/components/color-picker/color-picker.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/color-picker/color-picker.tsx b/packages/calcite-components/src/components/color-picker/color-picker.tsx index 125a9c4def7..e12d1c8c840 100644 --- a/packages/calcite-components/src/components/color-picker/color-picker.tsx +++ b/packages/calcite-components/src/components/color-picker/color-picker.tsx @@ -1406,9 +1406,8 @@ export class ColorPicker context.lineWidth = outlineWidth; context.stroke(); - const pattern = context.createPattern(this.getCheckeredBackgroundPattern(), "repeat"); - - if (color.alpha() < 1 && applyAlpha) { + if (applyAlpha && color.alpha() < 1) { + const pattern = context.createPattern(this.getCheckeredBackgroundPattern(), "repeat"); context.beginPath(); context.arc(x, y, radius - 3, startAngle, endAngle); context.fillStyle = pattern;