|
1 | | -import type { IColorSelectPanelRef } from '@/types' |
| 1 | +import type { |
| 2 | + IColorSelectPanelHueProps, |
| 3 | + IColorSelectPanelRef, |
| 4 | + ISharedRenderlessParamHooks, |
| 5 | + ISharedRenderlessParamUtils |
| 6 | +} from '@/types' |
2 | 7 | import type { Color } from '../utils/color' |
| 8 | +import { getClientXY } from '../utils/getClientXY' |
3 | 9 |
|
4 | | -export const setPosition = (el: HTMLElement, x: number, y: number) => { |
5 | | - el.style.top = `${y}px` |
6 | | - el.style.left = `${x}px` |
| 10 | +interface DomInit { |
| 11 | + thumb: IColorSelectPanelRef<HTMLElement | undefined> |
| 12 | + bar: IColorSelectPanelRef<HTMLElement | undefined> |
| 13 | + wrapper: IColorSelectPanelRef<HTMLElement | undefined> |
7 | 14 | } |
8 | | -export const getXBySaturation = (s: number, width: number) => (s * width) / 100 |
9 | | -export const getYByLight = (l: number, height: number) => ((100 - l) * height) / 100 |
10 | | -export const updatePosition = ( |
11 | | - event: MouseEvent | TouchEvent, |
12 | | - rect: DOMRect, |
13 | | - cursor: IColorSelectPanelRef<HTMLElement> |
14 | | -) => { |
15 | | - let x = (event as MouseEvent).clientX - rect.left |
16 | | - let y = (event as MouseEvent).clientY - rect.top |
17 | | - x = Math.max(0, x) |
18 | | - x = Math.min(x, rect.width) |
19 | | - y = Math.max(0, y) |
20 | | - y = Math.min(y, rect.height) |
21 | 15 |
|
22 | | - setPosition(cursor.value, x - (1 / 2) * cursor.value.offsetWidth, y - (1 / 2) * cursor.value.offsetWidth) |
23 | | - return { x, y } |
24 | | -} |
25 | | -export const calcSaturation = (x: number, width: number) => x / width |
26 | | -export const calcBrightness = (y: number, height: number) => 100 - (y / height) * 100 |
27 | | -export const getThumbTop = (wrapper: HTMLElement, thumb: HTMLElement, hue: number) => { |
28 | | - return Math.round((hue * (wrapper.offsetHeight - thumb.offsetHeight / 2)) / 360) |
29 | | -} |
30 | | - |
31 | | -export const resetCursor = ( |
32 | | - s: number, |
33 | | - v: number, |
34 | | - wrapper: IColorSelectPanelRef<HTMLElement>, |
35 | | - cursor: IColorSelectPanelRef<HTMLElement>, |
36 | | - thumb: IColorSelectPanelRef<HTMLElement>, |
37 | | - color: Color, |
38 | | - h: IColorSelectPanelRef<number> |
| 16 | +export const initState = ( |
| 17 | + props: IColorSelectPanelHueProps<Color>, |
| 18 | + { reactive, ref, computed }: ISharedRenderlessParamHooks |
39 | 19 | ) => { |
40 | | - const { width, height } = wrapper.value.getBoundingClientRect() |
41 | | - const x = getXBySaturation(s, width) - (1 / 2) * cursor.value.offsetWidth |
42 | | - const y = getYByLight(v, height) - (1 / 2) * cursor.value.offsetWidth |
43 | | - setPosition(cursor.value, x < 0 ? 0 : x, y < 0 ? 0 : y) |
44 | | - const thummbTop = getThumbTop(wrapper.value, thumb.value, color.get('h')) |
45 | | - thumb.value.style.top = `${thummbTop}px` |
46 | | - h.value = color.get('h') |
| 20 | + const hueValue = computed(() => props.color.get('hue')) |
| 21 | + const thumbTop = ref(0) |
| 22 | + const state = reactive({ hueValue, thumbTop }) |
| 23 | + return state |
47 | 24 | } |
48 | 25 |
|
49 | | -export const updateCursor = ( |
50 | | - wrapper: IColorSelectPanelRef<HTMLElement>, |
51 | | - cursor: IColorSelectPanelRef<HTMLElement>, |
52 | | - emit |
53 | | -) => { |
54 | | - return (color: Color, event: MouseEvent) => { |
55 | | - const rect = wrapper.value.getBoundingClientRect() |
56 | | - const { x, y } = updatePosition(event, rect, cursor) |
57 | | - color.set({ |
58 | | - s: calcSaturation(x, rect.width) * 100, |
59 | | - v: calcBrightness(y, rect.height), |
60 | | - h: color.get('h') |
61 | | - }) |
62 | | - emit('sv-update', { |
63 | | - s: color.get('s'), |
64 | | - v: color.get('v'), |
65 | | - h: color.get('h') |
66 | | - }) |
| 26 | +export const initDom = ({ ref }: ISharedRenderlessParamHooks): DomInit => { |
| 27 | + return { |
| 28 | + thumb: ref<HTMLElement>(), |
| 29 | + bar: ref<HTMLElement>(), |
| 30 | + wrapper: ref<HTMLElement>() |
67 | 31 | } |
68 | 32 | } |
69 | 33 |
|
70 | | -export const updateThumb = ( |
71 | | - bar: IColorSelectPanelRef<HTMLElement>, |
72 | | - thumb: IColorSelectPanelRef<HTMLElement>, |
73 | | - h: IColorSelectPanelRef<Number>, |
74 | | - emit |
| 34 | +export const useEvent = ( |
| 35 | + { thumb, bar }: DomInit, |
| 36 | + state: ReturnType<typeof initState>, |
| 37 | + props: IColorSelectPanelHueProps<Color>, |
| 38 | + { emit }: ISharedRenderlessParamUtils |
75 | 39 | ) => { |
76 | | - return (event: MouseEvent) => { |
77 | | - const e = event as MouseEvent |
78 | | - const rect = bar.value.getBoundingClientRect() |
79 | | - let top = e.clientY - rect.top |
| 40 | + const onSvReady = (update) => { |
| 41 | + emit('svReady', update) |
| 42 | + } |
| 43 | + const getThumbTop = () => { |
| 44 | + if (!thumb.value) { |
| 45 | + return 0 |
| 46 | + } |
| 47 | + const hue = props.color.get('hue') |
| 48 | + if (!bar.value) { |
| 49 | + return 0 |
| 50 | + } |
| 51 | + return (hue * (bar.value.offsetHeight - thumb.value.offsetHeight / 2)) / 360 |
| 52 | + } |
| 53 | + const update = () => { |
| 54 | + state.thumbTop = getThumbTop() |
| 55 | + } |
| 56 | + const onDrag = (event: MouseEvent | TouchEvent) => { |
| 57 | + if (!bar.value || !thumb.value) { |
| 58 | + return |
| 59 | + } |
| 60 | + const el = bar.value |
| 61 | + if (!el) { |
| 62 | + return |
| 63 | + } |
| 64 | + const rect = el?.getBoundingClientRect() |
| 65 | + const { clientY } = getClientXY(event) |
| 66 | + let top = clientY - rect.top |
| 67 | + |
80 | 68 | top = Math.min(top, rect.height - thumb.value.offsetHeight / 2) |
81 | 69 | top = Math.max(thumb.value.offsetHeight / 2, top) |
82 | | - thumb.value.style.top = `${top}px` |
83 | | - h.value = Math.round(((top - thumb.value.offsetHeight / 2) / (rect.height - thumb.value.offsetHeight)) * 360) |
84 | | - emit('hue-update', h.value) |
| 70 | + const hue = Math.round(((top - thumb.value.offsetHeight / 2) / (rect.height - thumb.value.offsetHeight)) * 360) |
| 71 | + state.thumbTop = top |
| 72 | + emit('hueUpdate', hue) |
| 73 | + props.color.set('hue', hue) |
85 | 74 | } |
| 75 | + return { update, onDrag, onSvReady } |
86 | 76 | } |
0 commit comments