Skip to content

Commit 623d491

Browse files
fix: 取色器支持移动端/触屏操作、UI优化
1 parent 8f991c9 commit 623d491

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

src/components/ColorPicker/Alpha.vue

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class="alpha-container"
99
ref="alphaRef"
1010
@mousedown="$event => handleMouseDown($event)"
11+
@touchstart="$event => handleMouseDown($event)"
1112
>
1213
<div class="alpha-pointer" :style="{ left: color.a * 100 + '%' }">
1314
<div class="alpha-picker"></div>
@@ -38,12 +39,18 @@ const gradientColor = computed(() => {
3839
})
3940
4041
const alphaRef = useTemplateRef<HTMLElement>('alphaRef')
41-
const handleChange = (e: MouseEvent) => {
42+
const handleChange = (e: MouseEvent | TouchEvent) => {
4243
e.preventDefault()
4344
if (!alphaRef.value) return
45+
46+
const isTouchEvent = !(e instanceof MouseEvent)
47+
if (isTouchEvent && (!e.changedTouches || !e.changedTouches[0])) return
48+
49+
const startPageX = isTouchEvent ? e.changedTouches[0].pageX : e.pageX
50+
4451
const containerWidth = alphaRef.value.clientWidth
4552
const xOffset = alphaRef.value.getBoundingClientRect().left + window.pageXOffset
46-
const left = e.pageX - xOffset
53+
const left = startPageX - xOffset
4754
let a
4855
4956
if (left < 0) a = 0
@@ -62,12 +69,16 @@ const handleChange = (e: MouseEvent) => {
6269
6370
const unbindEventListeners = () => {
6471
window.removeEventListener('mousemove', handleChange)
72+
window.removeEventListener('touchmove', handleChange)
6573
window.removeEventListener('mouseup', unbindEventListeners)
74+
window.removeEventListener('touchend', unbindEventListeners)
6675
}
67-
const handleMouseDown = (e: MouseEvent) => {
76+
const handleMouseDown = (e: MouseEvent | TouchEvent) => {
6877
handleChange(e)
6978
window.addEventListener('mousemove', handleChange)
79+
window.addEventListener('touchmove', handleChange)
7080
window.addEventListener('mouseup', unbindEventListeners)
81+
window.addEventListener('touchend', unbindEventListeners)
7182
}
7283
onUnmounted(unbindEventListeners)
7384
</script>

src/components/ColorPicker/Hue.vue

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
class="hue-container"
55
ref="hueRef"
66
@mousedown="$event => handleMouseDown($event)"
7+
@touchstart="$event => handleMouseDown($event)"
78
>
89
<div
910
class="hue-pointer"
@@ -51,13 +52,18 @@ watch(() => props.value, () => {
5152
})
5253
5354
const hueRef = useTemplateRef<HTMLElement>('hueRef')
54-
const handleChange = (e: MouseEvent) => {
55+
const handleChange = (e: MouseEvent | TouchEvent) => {
5556
e.preventDefault()
5657
if (!hueRef.value) return
5758
59+
const isTouchEvent = !(e instanceof MouseEvent)
60+
if (isTouchEvent && (!e.changedTouches || !e.changedTouches[0])) return
61+
62+
const startPageX = isTouchEvent ? e.changedTouches[0].pageX : e.pageX
63+
5864
const containerWidth = hueRef.value.clientWidth
5965
const xOffset = hueRef.value.getBoundingClientRect().left + window.pageXOffset
60-
const left = e.pageX - xOffset
66+
const left = startPageX - xOffset
6167
let h, percent
6268
6369
if (left < 0) h = 0
@@ -78,12 +84,16 @@ const handleChange = (e: MouseEvent) => {
7884
7985
const unbindEventListeners = () => {
8086
window.removeEventListener('mousemove', handleChange)
87+
window.removeEventListener('touchmove', handleChange)
8188
window.removeEventListener('mouseup', unbindEventListeners)
89+
window.removeEventListener('touchend', unbindEventListeners)
8290
}
83-
const handleMouseDown = (e: MouseEvent) => {
91+
const handleMouseDown = (e: MouseEvent | TouchEvent) => {
8492
handleChange(e)
8593
window.addEventListener('mousemove', handleChange)
94+
window.addEventListener('touchmove', handleChange)
8695
window.addEventListener('mouseup', unbindEventListeners)
96+
window.addEventListener('touchend', unbindEventListeners)
8797
}
8898
onUnmounted(unbindEventListeners)
8999
</script>

src/components/ColorPicker/Saturation.vue

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
ref="saturationRef"
55
:style="{ background: bgColor }"
66
@mousedown="$event => handleMouseDown($event)"
7+
@touchstart="$event => handleMouseDown($event)"
78
>
89
<div class="saturation-white"></div>
910
<div class="saturation-black"></div>
@@ -47,16 +48,22 @@ const emitChangeEvent = throttle(function(param: ColorFormats.HSVA) {
4748
}, 20, { leading: true, trailing: false })
4849
4950
const saturationRef = useTemplateRef<HTMLElement>('saturationRef')
50-
const handleChange = (e: MouseEvent) => {
51+
const handleChange = (e: MouseEvent | TouchEvent) => {
5152
e.preventDefault()
5253
if (!saturationRef.value) return
5354
55+
const isTouchEvent = !(e instanceof MouseEvent)
56+
if (isTouchEvent && (!e.changedTouches || !e.changedTouches[0])) return
57+
58+
const startPageX = isTouchEvent ? e.changedTouches[0].pageX : e.pageX
59+
const startPageY = isTouchEvent ? e.changedTouches[0].pageY : e.pageY
60+
5461
const containerWidth = saturationRef.value.clientWidth
5562
const containerHeight = saturationRef.value.clientHeight
5663
const xOffset = saturationRef.value.getBoundingClientRect().left + window.pageXOffset
5764
const yOffset = saturationRef.value.getBoundingClientRect().top + window.pageYOffset
58-
const left = clamp(e.pageX - xOffset, 0, containerWidth)
59-
const top = clamp(e.pageY - yOffset, 0, containerHeight)
65+
const left = clamp(startPageX - xOffset, 0, containerWidth)
66+
const top = clamp(startPageY - yOffset, 0, containerHeight)
6067
const saturation = left / containerWidth
6168
const bright = clamp(-(top / containerHeight) + 1, 0, 1)
6269
@@ -70,12 +77,16 @@ const handleChange = (e: MouseEvent) => {
7077
7178
const unbindEventListeners = () => {
7279
window.removeEventListener('mousemove', handleChange)
80+
window.removeEventListener('touchmove', handleChange)
7381
window.removeEventListener('mouseup', unbindEventListeners)
82+
window.removeEventListener('touchend', unbindEventListeners)
7483
}
75-
const handleMouseDown = (e: MouseEvent) => {
84+
const handleMouseDown = (e: MouseEvent | TouchEvent) => {
7685
handleChange(e)
7786
window.addEventListener('mousemove', handleChange)
87+
window.addEventListener('touchmove', handleChange)
7888
window.addEventListener('mouseup', unbindEventListeners)
89+
window.addEventListener('touchend', unbindEventListeners)
7990
}
8091
onUnmounted(unbindEventListeners)
8192
</script>

src/components/ColorPicker/index.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<div class="picker-presets">
3030
<div
3131
class="picker-presets-color"
32+
:class="{ 'white': c === '#ffffff' || c === '#fff' || c === 'rgb(255, 255, 255)' }"
3233
v-for="c in themeColors"
3334
:key="c"
3435
:style="{ background: c }"
@@ -53,9 +54,9 @@
5354

5455
<div class="picker-presets">
5556
<div
57+
class="picker-presets-color"
5658
v-for="c in standardColors"
5759
:key="c"
58-
class="picker-presets-color"
5960
:style="{ background: c }"
6061
@click="selectPresetColor(c)"
6162
></div>
@@ -64,9 +65,10 @@
6465
<div class="recent-colors-title" v-if="recentColors.length">最近使用:</div>
6566
<div class="picker-presets">
6667
<div
68+
class="picker-presets-color alpha"
69+
:class="{ 'white': c === '#ffffff' || c === '#fff' || c === 'rgb(255, 255, 255)' }"
6770
v-for="c in recentColors"
6871
:key="c"
69-
class="picker-presets-color alpha"
7072
@click="selectPresetColor(c)"
7173
>
7274
<div class="picker-presets-color-content" :style="{ background: c }"></div>
@@ -416,6 +418,12 @@ const customEyeDropper = () => {
416418
&.alpha {
417419
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAADBJREFUOE9jfPbs2X8GPEBSUhKfNAPjqAHDIgz+//+PNx08f/4cfzoYNYCBceiHAQC5flV5JzgrxQAAAABJRU5ErkJggg==);
418420
}
421+
422+
&.white::after {
423+
content: '';
424+
@include absolute-0();
425+
border: 1px solid #f5f5f5;
426+
}
419427
}
420428
.picker-presets-color-content {
421429
@include absolute-0();

src/views/Mobile/MobileEditor/ElementToolbar.vue

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
<div class="color custom">
7373
<Popover trigger="click">
7474
<template #content>
75-
<ColorPicker @update:modelValue="value => updateFontColor(value)" />
75+
<ColorPicker :modelValue="fontColor" @update:modelValue="value => updateFontColor(value)" />
7676
</template>
7777
<div class="color-block"></div>
7878
</Popover>
@@ -92,7 +92,7 @@
9292
<div class="color custom">
9393
<Popover trigger="click">
9494
<template #content>
95-
<ColorPicker @update:modelValue="value => updateFill(value)" />
95+
<ColorPicker :modelValue="fill" @update:modelValue="value => updateFill(value)" />
9696
</template>
9797
<div class="color-block"></div>
9898
</Popover>
@@ -231,6 +231,21 @@ const emitRichTextCommand = (command: string, value?: string) => {
231231
emitter.emit(EmitterEvents.RICH_TEXT_COMMAND, { action: { command, value } })
232232
}
233233
234+
const fontColor = computed(() => {
235+
if (!handleElement.value) return '#fff'
236+
if (handleElement.value.type === 'text' || (handleElement.value.type === 'shape' && handleElement.value.text?.content)) {
237+
return richTextAttrs.value.color
238+
}
239+
if (handleElement.value.type === 'table') {
240+
const data: TableCell[][] = JSON.parse(JSON.stringify(handleElement.value.data))
241+
return data[0][0].style?.color
242+
}
243+
if (handleElement.value.type === 'latex') {
244+
return handleElement.value.color
245+
}
246+
return '#fff'
247+
})
248+
234249
const updateFontColor = (color: string) => {
235250
if (!handleElement.value) return
236251
if (handleElement.value.type === 'text' || (handleElement.value.type === 'shape' && handleElement.value.text?.content)) {
@@ -251,6 +266,26 @@ const updateFontColor = (color: string) => {
251266
}
252267
}
253268
269+
const fill = computed(() => {
270+
if (!handleElement.value) return '#fff'
271+
272+
if (
273+
handleElement.value.type === 'text' ||
274+
handleElement.value.type === 'shape' ||
275+
handleElement.value.type === 'chart'
276+
) return handleElement.value.fill
277+
278+
if (handleElement.value.type === 'table') {
279+
const data: TableCell[][] = JSON.parse(JSON.stringify(handleElement.value.data))
280+
return data[0][0].style?.backcolor
281+
}
282+
283+
if (handleElement.value.type === 'audio' || handleElement.value.type === 'line') {
284+
return handleElement.value.color
285+
}
286+
return '#fff'
287+
})
288+
254289
const updateFill = (color: string) => {
255290
if (!handleElement.value) return
256291
if (

0 commit comments

Comments
 (0)