Skip to content

Commit be334c5

Browse files
GaoNeng-wWwkagol
authored andcommitted
refactor: extract alpha select state init, api init, event init to index.ts
1 parent b68884d commit be334c5

File tree

4 files changed

+86
-82
lines changed

4 files changed

+86
-82
lines changed
Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,82 @@
1-
import type { IColorSelectPanelRef } from '@/types'
1+
import type { IColorSelectPanelAlphProps, IColorSelectPanelRef, ISharedRenderlessParamHooks } from '@/types'
2+
import type { Color } from '../utils/color'
3+
import { getClientXY } from '../utils/getClientXY'
24

3-
export const calcLeftByAlpha = (wrapper: HTMLElement, thumb: HTMLElement, alpha: number) => {
4-
return Math.round((alpha * (wrapper.offsetWidth - thumb.offsetWidth / 2)) / 100)
5+
type State = ReturnType<typeof initState>
6+
7+
export const initState = ({ ref, reactive }: ISharedRenderlessParamHooks) => {
8+
const background = ref('')
9+
const left = ref(0)
10+
const state = reactive({ background, left })
11+
return state
512
}
613

7-
export const updateThumb = (alpha: number, thumb: HTMLElement, wrapper: HTMLElement) => {
8-
thumb.style.left = `${calcLeftByAlpha(wrapper, thumb, alpha)}px`
14+
export const useEvent = (
15+
state: State,
16+
slider: IColorSelectPanelRef<HTMLElement | undefined>,
17+
alphaWrapper: IColorSelectPanelRef<HTMLElement | undefined>,
18+
alphaThumb: IColorSelectPanelRef<HTMLElement | undefined>,
19+
props: IColorSelectPanelAlphProps<Color>
20+
) => {
21+
const onDrag = (event: MouseEvent | TouchEvent) => {
22+
if (!slider.value || !alphaThumb.value) {
23+
return
24+
}
25+
const el = alphaWrapper.value!
26+
const rect = el.getBoundingClientRect()
27+
const { clientX } = getClientXY(event)
28+
let left = clientX - rect.left
29+
left = Math.max(alphaThumb.value.offsetWidth / 2, left)
30+
left = Math.min(left, rect.width - alphaThumb.value.offsetWidth / 2)
31+
const alpha = Math.round(
32+
((left - alphaThumb.value.offsetWidth / 2) / (rect.width - alphaThumb.value.offsetWidth)) * 100
33+
)
34+
props.color.set('alpha', alpha)
35+
}
36+
const onClick = (event: MouseEvent | TouchEvent) => {
37+
if (event.target !== alphaThumb.value) {
38+
onDrag(event)
39+
}
40+
}
41+
const getLeft = () => {
42+
const thumb = alphaThumb.value
43+
if (!thumb) {
44+
return 0
45+
}
46+
const el = alphaWrapper.value
47+
if (!el) {
48+
return 0
49+
}
50+
const alpha = props.color.get('alpha')
51+
return (alpha * (el.offsetWidth - thumb.offsetWidth / 2)) / 100
52+
}
53+
const getBackground = () => {
54+
if (props.color && props.color.value) {
55+
const { r, g, b } = props.color.toRgb()
56+
return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)`
57+
}
58+
return ''
59+
}
60+
const update = () => {
61+
state.left = getLeft()
62+
state.background = getBackground()
63+
}
64+
return { onDrag, onClick, update }
965
}
1066

11-
export const onDrag = (
12-
event: MouseEvent,
13-
bar: IColorSelectPanelRef<HTMLElement>,
14-
thumb: IColorSelectPanelRef<HTMLElement>,
15-
alpha: IColorSelectPanelRef<number>
67+
export const initWatch = (
68+
props: IColorSelectPanelAlphProps<Color>,
69+
update: () => void,
70+
{ watch }: ISharedRenderlessParamHooks
1671
) => {
17-
const rect = bar.value.getBoundingClientRect()
18-
const { clientX } = event
19-
let left = clientX - rect.left
20-
left = Math.max(thumb.value.offsetWidth / 2, left)
21-
left = Math.min(left, rect.width - thumb.value.offsetWidth / 2)
22-
alpha.value = Math.round(((left - thumb.value.offsetWidth / 2) / (rect.width - thumb.value.offsetWidth)) * 100)
72+
watch(
73+
() => props.color.get('alpha'),
74+
() => update(),
75+
{ deep: true }
76+
)
77+
watch(
78+
() => props.color,
79+
() => update(),
80+
{ deep: true }
81+
)
2382
}

packages/renderless/src/color-select-panel/alpha-select/vue.ts

Lines changed: 9 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,22 @@
11
import type { IColorSelectPanelAlphProps, ISharedRenderlessParamHooks, ISharedRenderlessParamUtils } from '@/types'
22
import type { Color } from '../utils/color'
3-
import { getClientXY } from '../utils/getClientXY'
43
import { draggable } from '../utils/use-drag'
4+
import { initState, initWatch, useEvent } from '.'
55

66
export const api = ['state', 'color', 'slider', 'alphaWrapper', 'alphaThumb', 'onClick']
77

88
export const renderless = (
99
props: IColorSelectPanelAlphProps<Color>,
10-
{ onMounted, watch, ref, reactive }: ISharedRenderlessParamHooks,
11-
{ emit }: ISharedRenderlessParamUtils
10+
hooks: ISharedRenderlessParamHooks,
11+
utils: ISharedRenderlessParamUtils
1212
) => {
13+
const { onMounted, ref } = hooks
14+
const { emit } = utils
1315
const slider = ref<HTMLElement>()
1416
const alphaWrapper = ref<HTMLElement>()
1517
const alphaThumb = ref<HTMLElement>()
16-
const left = ref(0)
17-
const background = ref('')
18-
const state = reactive({
19-
background,
20-
left
21-
})
22-
const onDrag = (event: MouseEvent | TouchEvent) => {
23-
if (!slider.value || !alphaThumb.value) {
24-
return
25-
}
26-
const el = alphaWrapper.value!
27-
const rect = el.getBoundingClientRect()
28-
const { clientX } = getClientXY(event)
29-
let left = clientX - rect.left
30-
left = Math.max(alphaThumb.value.offsetWidth / 2, left)
31-
left = Math.min(left, rect.width - alphaThumb.value.offsetWidth / 2)
32-
const alpha = Math.round(
33-
((left - alphaThumb.value.offsetWidth / 2) / (rect.width - alphaThumb.value.offsetWidth)) * 100
34-
)
35-
props.color.set('alpha', alpha)
36-
}
37-
const onClick = (event: MouseEvent | TouchEvent) => {
38-
if (event.target !== alphaThumb.value) {
39-
onDrag(event)
40-
}
41-
}
42-
const getLeft = () => {
43-
const thumb = alphaThumb.value
44-
if (!thumb) {
45-
return 0
46-
}
47-
const el = alphaWrapper.value
48-
if (!el) {
49-
return 0
50-
}
51-
const alpha = props.color.get('alpha')
52-
return (alpha * (el.offsetWidth - thumb.offsetWidth / 2)) / 100
53-
}
54-
55-
const getBackground = () => {
56-
if (props.color && props.color.value) {
57-
const { r, g, b } = props.color.toRgb()
58-
return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)`
59-
}
60-
return ''
61-
}
62-
63-
const update = () => {
64-
left.value = getLeft()
65-
background.value = getBackground()
66-
}
18+
const state = initState(hooks)
19+
const { update, onClick, onDrag } = useEvent(state, slider, alphaWrapper, alphaThumb, props)
6720
onMounted(() => {
6821
if (!slider.value || !alphaThumb.value) {
6922
return
@@ -83,16 +36,8 @@ export const renderless = (
8336
emit('ready', update)
8437
})
8538

86-
watch(
87-
() => props.color.get('alpha'),
88-
() => update(),
89-
{ deep: true }
90-
)
91-
watch(
92-
() => props.color,
93-
() => update(),
94-
{ deep: true }
95-
)
39+
initWatch(props, update, hooks)
40+
9641
const api = {
9742
state,
9843
slider,

packages/vue/src/color-select-panel/src/components/alpha-select.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { defineComponent, setup } from '@opentiny/vue-common'
2424
import { renderless, api } from '@opentiny/vue-renderless/color-select-panel/alpha-select/vue'
2525
2626
export default defineComponent({
27-
emits: ['alpha-update', 'ready'],
27+
emits: ['ready'],
2828
props: {
2929
color: {
3030
type: Object

packages/vue/src/color-select-panel/src/pc.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div class="tiny-color-select-panel" @click.stop v-if="state.showPicker" v-clickoutside="onClickOutside">
33
<hue-select :color="state.color" @hue-ready="onHueReady" @sv-ready="onSvReady" />
4-
<alpha-select v-if="alpha" :color="state.color" @alpha-update="onAlphaUpdate" @ready="onAlphaReady" />
4+
<alpha-select v-if="alpha" :color="state.color" @ready="onAlphaReady" />
55
<div class="tiny-color-select-panel__tools">
66
<tiny-input v-model="state.input" size="small" />
77
<div class="tiny-color-select-panel__tools-btns">

0 commit comments

Comments
 (0)