From 9e378dfed10d478aa388460cf304ac58172e8fc1 Mon Sep 17 00:00:00 2001 From: Kael Date: Fri, 8 Sep 2023 18:40:37 +1000 Subject: [PATCH] fix(VColorPicker): don't update color when canvas resizes fixes #18231 --- .../VColorPicker/VColorPickerCanvas.tsx | 49 +++++++++---------- .../__tests__/VColorPicker.spec.cy.tsx | 4 +- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx b/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx index 2b3a3c9940c..88ba65d89b9 100644 --- a/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx +++ b/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx @@ -46,8 +46,26 @@ export const VColorPickerCanvas = defineComponent({ setup (props, { emit }) { const isInteracting = shallowRef(false) - const isOutsideUpdate = shallowRef(false) - const dotPosition = ref({ x: 0, y: 0 }) + const canvasRef = ref() + const canvasWidth = shallowRef(parseFloat(props.width)) + const canvasHeight = shallowRef(parseFloat(props.height)) + + const _dotPosition = ref({ x: 0, y: 0 }) + const dotPosition = computed({ + get: () => _dotPosition.value, + set (val) { + if (!canvasRef.value) return + + const { x, y } = val + + emit('update:color', { + h: props.color?.h ?? 0, + s: clamp(x, 0, canvasWidth.value) / canvasWidth.value, + v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value, + a: props.color?.a ?? 1, + }) + }, + }) const dotStyles = computed(() => { const { x, y } = dotPosition.value @@ -60,9 +78,6 @@ export const VColorPickerCanvas = defineComponent({ } }) - const canvasRef = ref() - const canvasWidth = shallowRef(parseFloat(props.width)) - const canvasHeight = shallowRef(parseFloat(props.height)) const { resizeRef } = useResizeObserver(entries => { if (!resizeRef.value?.offsetParent) return @@ -113,24 +128,6 @@ export const VColorPickerCanvas = defineComponent({ window.removeEventListener('touchend', handleMouseUp) } - watch(dotPosition, () => { - if (isOutsideUpdate.value) { - isOutsideUpdate.value = false - return - } - - if (!canvasRef.value) return - - const { x, y } = dotPosition.value - - emit('update:color', { - h: props.color?.h ?? 0, - s: clamp(x, 0, canvasWidth.value) / canvasWidth.value, - v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value, - a: props.color?.a ?? 1, - }) - }) - function updateCanvas () { if (!canvasRef.value) return @@ -155,7 +152,7 @@ export const VColorPickerCanvas = defineComponent({ watch(() => props.color?.h, updateCanvas, { immediate: true }) watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => { updateCanvas() - dotPosition.value = { + _dotPosition.value = { x: dotPosition.value.x * newVal[0] / oldVal[0], y: dotPosition.value.y * newVal[1] / oldVal[1], } @@ -167,9 +164,7 @@ export const VColorPickerCanvas = defineComponent({ return } - isOutsideUpdate.value = true - - dotPosition.value = props.color ? { + _dotPosition.value = props.color ? { x: props.color.s * canvasWidth.value, y: (1 - props.color.v) * canvasHeight.value, } : { x: 0, y: 0 } diff --git a/packages/vuetify/src/components/VColorPicker/__tests__/VColorPicker.spec.cy.tsx b/packages/vuetify/src/components/VColorPicker/__tests__/VColorPicker.spec.cy.tsx index 7783777f430..ba89a4f6946 100644 --- a/packages/vuetify/src/components/VColorPicker/__tests__/VColorPicker.spec.cy.tsx +++ b/packages/vuetify/src/components/VColorPicker/__tests__/VColorPicker.spec.cy.tsx @@ -213,7 +213,7 @@ describe('VColorPicker', () => { it('should emit value when changing hue slider', () => { cy.mount(() => ( - + )) @@ -231,7 +231,7 @@ describe('VColorPicker', () => { it('should emit value when changing alpha slider', () => { cy.mount(() => ( - + ))