{"version":3,"file":"VColorPickerCanvas.mjs","names":["useResizeObserver","clamp","convertToUnit","defineComponent","getEventCoordinates","useRender","computed","onMounted","ref","watch","VColorPickerCanvas","name","props","color","type","Object","disabled","Boolean","dotSize","Number","String","default","height","width","emits","hue","setup","emit","isInteracting","isOutsideUpdate","dotPosition","x","y","dotStyles","value","radius","parseInt","transform","canvasRef","canvasWidth","parseFloat","canvasHeight","resizeRef","entries","offsetParent","contentRect","updateDotPosition","rect","left","top","handleClick","e","clientX","clientY","getBoundingClientRect","handleMouseDown","preventDefault","window","addEventListener","handleMouseMove","handleMouseUp","coords","removeEventListener","h","s","v","a","updateCanvas","canvas","ctx","getContext","saturationGradient","createLinearGradient","addColorStop","fillStyle","fillRect","valueGradient","immediate","newVal","oldVal","flush","deep"],"sources":["../../../src/components/VColorPicker/VColorPickerCanvas.tsx"],"sourcesContent":["// Styles\nimport './VColorPickerCanvas.sass'\n\n// Composables\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { clamp, convertToUnit, defineComponent, getEventCoordinates, useRender } from '@/util'\nimport { computed, onMounted, ref, watch } from 'vue'\n\n// Types\nimport type { HSV } from '@/util'\nimport type { PropType } from 'vue'\n\nexport const VColorPickerCanvas = defineComponent({\n  name: 'VColorPickerCanvas',\n\n  props: {\n    color: {\n      type: Object as PropType<HSV | null>,\n    },\n    disabled: Boolean,\n    dotSize: {\n      type: [Number, String],\n      default: 10,\n    },\n    height: {\n      type: [Number, String],\n      default: 150,\n    },\n    width: {\n      type: [Number, String],\n      default: 300,\n    },\n  },\n\n  emits: {\n    'update:color': (color: HSV) => true,\n    'update:position': (hue: any) => true,\n  },\n\n  setup (props, { emit }) {\n    const isInteracting = ref(false)\n    const isOutsideUpdate = ref(false)\n    const dotPosition = ref({ x: 0, y: 0 })\n\n    const dotStyles = computed(() => {\n      const { x, y } = dotPosition.value\n      const radius = parseInt(props.dotSize, 10) / 2\n\n      return {\n        width: convertToUnit(props.dotSize),\n        height: convertToUnit(props.dotSize),\n        transform: `translate(${convertToUnit(x - radius)}, ${convertToUnit(y - radius)})`,\n      }\n    })\n\n    const canvasRef = ref<HTMLCanvasElement | null>()\n    const canvasWidth = ref(parseFloat(props.width))\n    const canvasHeight = ref(parseFloat(props.height))\n    const { resizeRef } = useResizeObserver(entries => {\n      if (!resizeRef.value?.offsetParent) return\n\n      const { width, height } = entries[0].contentRect\n\n      canvasWidth.value = width\n      canvasHeight.value = height\n    })\n\n    function updateDotPosition (x: number, y: number, rect: DOMRect) {\n      const { left, top, width, height } = rect\n      dotPosition.value = {\n        x: clamp(x - left, 0, width),\n        y: clamp(y - top, 0, height),\n      }\n    }\n\n    function handleClick (e: MouseEvent) {\n      if (props.disabled || !canvasRef.value) return\n\n      updateDotPosition(e.clientX, e.clientY, canvasRef.value.getBoundingClientRect())\n    }\n\n    function handleMouseDown (e: MouseEvent | TouchEvent) {\n      // To prevent selection while moving cursor\n      e.preventDefault()\n\n      if (props.disabled) return\n\n      isInteracting.value = true\n\n      window.addEventListener('mousemove', handleMouseMove)\n      window.addEventListener('mouseup', handleMouseUp)\n      window.addEventListener('touchmove', handleMouseMove)\n      window.addEventListener('touchend', handleMouseUp)\n    }\n\n    function handleMouseMove (e: MouseEvent | TouchEvent) {\n      if (props.disabled || !canvasRef.value) return\n\n      isInteracting.value = true\n\n      const coords = getEventCoordinates(e)\n\n      updateDotPosition(coords.clientX, coords.clientY, canvasRef.value.getBoundingClientRect())\n    }\n\n    function handleMouseUp () {\n      window.removeEventListener('mousemove', handleMouseMove)\n      window.removeEventListener('mouseup', handleMouseUp)\n      window.removeEventListener('touchmove', handleMouseMove)\n      window.removeEventListener('touchend', handleMouseUp)\n    }\n\n    watch(dotPosition, () => {\n      if (isOutsideUpdate.value) {\n        isOutsideUpdate.value = false\n        return\n      }\n\n      if (!canvasRef.value) return\n\n      const { x, y } = dotPosition.value\n\n      emit('update:color', {\n        h: props.color?.h ?? 0,\n        s: clamp(x, 0, canvasWidth.value) / canvasWidth.value,\n        v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value,\n        a: props.color?.a ?? 1,\n      })\n    })\n\n    function updateCanvas () {\n      if (!canvasRef.value) return\n\n      const canvas = canvasRef.value\n      const ctx = canvas.getContext('2d')\n\n      if (!ctx) return\n\n      const saturationGradient = ctx.createLinearGradient(0, 0, canvas.width, 0)\n      saturationGradient.addColorStop(0, 'hsla(0, 0%, 100%, 1)') // white\n      saturationGradient.addColorStop(1, `hsla(${props.color?.h ?? 0}, 100%, 50%, 1)`)\n      ctx.fillStyle = saturationGradient\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n      const valueGradient = ctx.createLinearGradient(0, 0, 0, canvas.height)\n      valueGradient.addColorStop(0, 'hsla(0, 0%, 100%, 0)') // transparent\n      valueGradient.addColorStop(1, 'hsla(0, 0%, 0%, 1)') // black\n      ctx.fillStyle = valueGradient\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n    }\n\n    watch(() => props.color?.h, updateCanvas, { immediate: true })\n    watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => {\n      updateCanvas()\n      dotPosition.value = {\n        x: dotPosition.value.x * newVal[0] / oldVal[0],\n        y: dotPosition.value.y * newVal[1] / oldVal[1],\n      }\n    }, { flush: 'post' })\n\n    watch(() => props.color, () => {\n      if (isInteracting.value) {\n        isInteracting.value = false\n        return\n      }\n\n      isOutsideUpdate.value = true\n\n      dotPosition.value = props.color ? {\n        x: props.color.s * canvasWidth.value,\n        y: (1 - props.color.v) * canvasHeight.value,\n      } : { x: 0, y: 0 }\n    }, { deep: true, immediate: true })\n\n    onMounted(() => updateCanvas())\n\n    useRender(() => (\n      <div\n        ref={ resizeRef }\n        class=\"v-color-picker-canvas\"\n        onClick={ handleClick }\n        onMousedown={ handleMouseDown }\n        onTouchstart={ handleMouseDown }\n      >\n        <canvas\n          ref={ canvasRef }\n          width={ canvasWidth.value }\n          height={ canvasHeight.value }\n        />\n        { props.color && (\n          <div\n            class={[\n              'v-color-picker-canvas__dot',\n              {\n                'v-color-picker-canvas__dot--disabled': props.disabled,\n              },\n            ]}\n            style={ dotStyles.value }\n          />\n        )}\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VColorPickerCanvas = InstanceType<typeof VColorPickerCanvas>\n"],"mappings":"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"}