{"version":3,"file":"Board.mjs","sources":["../../../../../src/components/color-picker-v3/src/common/Board.vue"],"sourcesContent":["<template>\n  <div\n    ref=\"boardElement\"\n    :class=\"['vc-saturation', { 'vc-saturation__chrome': round, 'vc-saturation__hidden': hide }]\"\n    :style=\"{ backgroundColor: state.hueColor }\"\n    @click=\"onClickBoard\"\n  >\n    <div class=\"vc-saturation__white\"></div>\n    <div class=\"vc-saturation__black\"></div>\n    <div class=\"vc-saturation__cursor\" ref=\"cursorElement\" :style=\"getCursorStyle\">\n      <div></div>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import {\n    computed,\n    defineComponent,\n    getCurrentInstance,\n    onMounted,\n    reactive,\n    ref,\n    watch,\n  } from 'vue';\n  import propTypes from 'vue-types';\n  import { clamp, Color } from '../utils/color';\n  import { whenever } from '@vueuse/core';\n  import { merge } from 'lodash-es';\n  import { DOMUtils } from '@aesoper/normal-utils';\n\n  export default defineComponent({\n    name: 'Board',\n    props: {\n      color: propTypes.instanceOf(Color),\n      round: propTypes.bool.def(false),\n      hide: propTypes.bool.def(true),\n    },\n    emits: ['change'],\n    setup(props, { emit }) {\n      const instance = getCurrentInstance();\n      const hueHsv = {\n        h: props.color?.hue || 0,\n        s: 1,\n        v: 1,\n      };\n\n      const hueColor = new Color(hueHsv).toHexString();\n\n      const state = reactive({\n        hueColor,\n        saturation: props.color?.saturation || 0,\n        brightness: props.color?.brightness || 0,\n      });\n\n      const cursorTop = ref(0);\n      const cursorLeft = ref(0);\n\n      const cursorElement = ref<HTMLElement | null>();\n      const boardElement = ref<HTMLElement | null>();\n\n      const getCursorStyle = computed(() => {\n        return {\n          top: cursorTop.value + 'px',\n          left: cursorLeft.value + 'px',\n        };\n      });\n\n      const updatePosition = () => {\n        if (instance) {\n          const el = instance.vnode.el;\n          cursorLeft.value = state.saturation * el?.clientWidth;\n          cursorTop.value = (1 - state.brightness) * el?.clientHeight;\n        }\n      };\n\n      const onClickBoard = (event: Event) => {\n        const target = event.target;\n\n        if (target !== boardElement.value) {\n          handleDrag(event as MouseEvent);\n        }\n      };\n\n      const handleDrag = (event: MouseEvent) => {\n        if (instance) {\n          const el = instance.vnode.el;\n          const rect = el?.getBoundingClientRect();\n\n          let left = event.clientX - rect.left;\n          let top = event.clientY - rect.top;\n\n          left = clamp(left, 0, rect.width);\n          top = clamp(top, 0, rect.height);\n\n          const saturation = left / rect.width;\n          const bright = clamp(-(top / rect.height) + 1, 0, 1);\n\n          cursorLeft.value = left;\n          cursorTop.value = top;\n\n          state.saturation = saturation;\n          state.brightness = bright;\n\n          emit('change', saturation, bright);\n        }\n      };\n\n      onMounted(() => {\n        if (instance && instance.vnode.el && cursorElement.value) {\n          DOMUtils.triggerDragEvent(cursorElement.value, {\n            drag: (event: Event) => {\n              handleDrag(event as MouseEvent);\n            },\n            end: (event) => {\n              handleDrag(event as MouseEvent);\n            },\n          });\n\n          updatePosition();\n        }\n      });\n\n      watch(\n        () => props.color,\n        (value) => {\n          if (value) {\n            merge(state, {\n              hueColor: new Color({ h: value.hue, s: 1, v: 1 }).toHexString(),\n              saturation: value.saturation,\n              brightness: value.brightness,\n            });\n            updatePosition();\n          }\n        },\n        { deep: true },\n      );\n\n      return { state, cursorElement, getCursorStyle, onClickBoard };\n    },\n  });\n</script>\n\n<style lang=\"scss\">\n  .vc-saturation {\n    position: relative;\n    margin-bottom: 15px;\n    width: 100%;\n    height: 125px;\n\n    &__chrome {\n      border-top-left-radius: 5px;\n      border-top-right-radius: 5px;\n      border-color: transparent;\n    }\n\n    &__hidden {\n      overflow: hidden;\n    }\n\n    &__white,\n    &__black {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n    }\n\n    &__black {\n      background: linear-gradient(0deg, #000, transparent);\n    }\n\n    &__white {\n      background: linear-gradient(90deg, #fff, hsla(0, 0%, 100%, 0));\n    }\n\n    &__cursor {\n      position: absolute;\n\n      div {\n        transform: translate(-5px, -5px);\n        box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37);\n        width: 10px;\n        height: 10px;\n        border: 1px solid white;\n        border-radius: 50%;\n        cursor: pointer;\n      }\n    }\n  }\n</style>\n"],"names":["_createElementVNode","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle"],"mappings":";;;;;mCAUiBA,kBAAA,CAAA,KAAA,EAAA,EAAA,KAAA,EAAA,sBAAA,EAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA;;MAAX,UAAW,mBAAAA,kBAAA,CAAA,KAAA,EAAA,IAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA;;;;SART,WAAc,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;AACZ,EAAA,OAAAC,SAAA,EAAA,EAAAC,kBAAA,CAAA,KAAA,EAAA;AAAA,IACL,GAAK,EAAA,cAAA;AAAA,IACL,KAAA,EAAKC,4DAAE,IAAY,CAAA,KAAA,EAAA,uBAAA,EAAA,IAAA,CAAA,IAAA,EAAA,CAAA,CAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,EAAA,eAAA,EAAA,IAAA,CAAA,KAAA,CAAA,QAAA,EAAA,CAAA;IAEpB,OAAwC,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,YAAA,IAAA,IAAA,CAAA,YAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,GACxC,EAAA;AAAA,IACA,UAAA;AAAA,IAAA,UAAA;uBAAuC,KAAe,EAAA;AAAA,MAAE,KAAK,EAAA,uBAAA;AAAA,MAAA,GAAA,EAAA,eAAA;;;;;;;;;"}