mirror of
https://github.com/element-plus/element-plus.git
synced 2025-01-18 10:59:10 +08:00
fix: coler picker support touch (#4477)
* fix: coler picker support touch * fix: update * fix: add getClientXY util * fix: move getClientXY to util/dom
This commit is contained in:
parent
900d62a77e
commit
94e0421623
@ -21,11 +21,12 @@ const _mount = (template: string, data: () => { [key: string]: any }) => {
|
||||
type ColorPickerVM = ComponentPublicInstance<{
|
||||
handleClick: (opt: {
|
||||
target: Nullable<HTMLElement>
|
||||
type: string
|
||||
clientX: number
|
||||
clientY: number
|
||||
}) => void
|
||||
thumbTop: number
|
||||
handleDrag: (opt: { clientX: number; clientY: number }) => void
|
||||
handleDrag: (opt: { type: string; clientX: number; clientY: number }) => void
|
||||
}>
|
||||
|
||||
describe('Color-picker', () => {
|
||||
@ -188,6 +189,7 @@ describe('Color-picker', () => {
|
||||
.mockReturnValue(4)
|
||||
;(hueSlideWrapper.vm as ColorPickerVM).handleClick({
|
||||
target: null,
|
||||
type: 'mouseup',
|
||||
clientX: 0,
|
||||
clientY: 100,
|
||||
})
|
||||
@ -229,6 +231,7 @@ describe('Color-picker', () => {
|
||||
.mockReturnValue(4)
|
||||
;(hueSlideWrapper.vm as ColorPickerVM).handleClick({
|
||||
target: null,
|
||||
type: 'mouseup',
|
||||
clientX: 0,
|
||||
clientY: 100,
|
||||
})
|
||||
@ -268,6 +271,7 @@ describe('Color-picker', () => {
|
||||
.mockReturnValue(4)
|
||||
;(alphaWrapper.vm as ColorPickerVM).handleClick({
|
||||
target: null,
|
||||
type: 'mouseup',
|
||||
clientX: 50,
|
||||
clientY: 0,
|
||||
})
|
||||
@ -289,7 +293,11 @@ describe('Color-picker', () => {
|
||||
await wrapper.find('.el-color-picker__trigger').trigger('click')
|
||||
const colorPickerWrapper = wrapper.findComponent(ColorPicker)
|
||||
const svPanelWrapper = colorPickerWrapper.findComponent({ ref: 'svPanel' })
|
||||
;(svPanelWrapper.vm as ColorPickerVM).handleDrag({ clientX: 0, clientY: 0 })
|
||||
;(svPanelWrapper.vm as ColorPickerVM).handleDrag({
|
||||
type: 'mousemove',
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
})
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.vm.color._saturation !== 50).toBeTruthy()
|
||||
expect(wrapper.vm.color._value !== 50).toBeTruthy()
|
||||
@ -404,6 +412,7 @@ describe('Color-picker', () => {
|
||||
.mockReturnValue(4)
|
||||
;(hueSlideWrapper.vm as ColorPickerVM).handleClick({
|
||||
target: null,
|
||||
type: 'mouseup',
|
||||
clientX: 0,
|
||||
clientY: 1000,
|
||||
})
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
getCurrentInstance,
|
||||
shallowRef,
|
||||
} from 'vue'
|
||||
import { getClientXY } from '@element-plus/utils/dom'
|
||||
import draggable from '../draggable'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
@ -112,9 +113,10 @@ export default defineComponent({
|
||||
function handleDrag(event) {
|
||||
const el = instance.vnode.el as HTMLElement
|
||||
const rect = el.getBoundingClientRect()
|
||||
const { clientX, clientY } = getClientXY(event)
|
||||
|
||||
if (!props.vertical) {
|
||||
let left = event.clientX - rect.left
|
||||
let left = clientX - rect.left
|
||||
left = Math.max(thumb.value.offsetWidth / 2, left)
|
||||
left = Math.min(left, rect.width - thumb.value.offsetWidth / 2)
|
||||
|
||||
@ -127,7 +129,7 @@ export default defineComponent({
|
||||
)
|
||||
)
|
||||
} else {
|
||||
let top = event.clientY - rect.top
|
||||
let top = clientY - rect.top
|
||||
top = Math.max(thumb.value.offsetHeight / 2, top)
|
||||
top = Math.min(top, rect.height - thumb.value.offsetHeight / 2)
|
||||
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
getCurrentInstance,
|
||||
defineComponent,
|
||||
} from 'vue'
|
||||
import { getClientXY } from '@element-plus/utils/dom'
|
||||
import draggable from '../draggable'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
@ -56,6 +57,7 @@ export default defineComponent({
|
||||
update()
|
||||
}
|
||||
)
|
||||
|
||||
// methods
|
||||
function handleClick(event: Event) {
|
||||
const target = event.target
|
||||
@ -64,13 +66,15 @@ export default defineComponent({
|
||||
handleDrag(event)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDrag(event) {
|
||||
const el = instance.vnode.el as HTMLElement
|
||||
const rect = el.getBoundingClientRect()
|
||||
const { clientX, clientY } = getClientXY(event)
|
||||
let hue
|
||||
|
||||
if (!props.vertical) {
|
||||
let left = event.clientX - rect.left
|
||||
let left = clientX - rect.left
|
||||
left = Math.min(left, rect.width - thumb.value.offsetWidth / 2)
|
||||
left = Math.max(thumb.value.offsetWidth / 2, left)
|
||||
|
||||
@ -80,7 +84,7 @@ export default defineComponent({
|
||||
360
|
||||
)
|
||||
} else {
|
||||
let top = event.clientY - rect.top
|
||||
let top = clientY - rect.top
|
||||
|
||||
top = Math.min(top, rect.height - thumb.value.offsetHeight / 2)
|
||||
top = Math.max(thumb.value.offsetHeight / 2, top)
|
||||
@ -92,6 +96,7 @@ export default defineComponent({
|
||||
}
|
||||
props.color.set('hue', hue)
|
||||
}
|
||||
|
||||
function getThumbLeft() {
|
||||
const el = instance.vnode.el
|
||||
|
||||
@ -114,10 +119,12 @@ export default defineComponent({
|
||||
(hue * (el.offsetHeight - thumb.value.offsetHeight / 2)) / 360
|
||||
)
|
||||
}
|
||||
|
||||
function update() {
|
||||
thumbLeft.value = getThumbLeft()
|
||||
thumbTop.value = getThumbTop()
|
||||
}
|
||||
|
||||
// mounded
|
||||
onMounted(() => {
|
||||
const dragConfig = {
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
} from 'vue'
|
||||
import { getClientXY } from '@element-plus/utils/dom'
|
||||
import draggable from '../draggable'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
@ -54,6 +55,7 @@ export default defineComponent({
|
||||
const value = props.color.get('value')
|
||||
return { hue, value }
|
||||
})
|
||||
|
||||
// methods
|
||||
function update() {
|
||||
const saturation = props.color.get('saturation')
|
||||
@ -71,9 +73,10 @@ export default defineComponent({
|
||||
function handleDrag(event) {
|
||||
const el = instance.vnode.el
|
||||
const rect = el.getBoundingClientRect()
|
||||
const { clientX, clientY } = getClientXY(event)
|
||||
|
||||
let left = event.clientX - rect.left
|
||||
let top = event.clientY - rect.top
|
||||
let left = clientX - rect.left
|
||||
let top = clientY - rect.top
|
||||
left = Math.max(0, left)
|
||||
left = Math.min(left, rect.width)
|
||||
|
||||
@ -87,6 +90,7 @@ export default defineComponent({
|
||||
value: 100 - (top / rect.height) * 100,
|
||||
})
|
||||
}
|
||||
|
||||
// watch
|
||||
watch(
|
||||
() => colorValue.value,
|
||||
|
@ -19,6 +19,8 @@ export default function (element: HTMLElement, options: IOptions) {
|
||||
const upFn = function (event: Event) {
|
||||
off(document, 'mousemove', moveFn)
|
||||
off(document, 'mouseup', upFn)
|
||||
off(document, 'touchmove', moveFn)
|
||||
off(document, 'touchend', upFn)
|
||||
document.onselectstart = null
|
||||
document.ondragstart = null
|
||||
|
||||
@ -27,15 +29,21 @@ export default function (element: HTMLElement, options: IOptions) {
|
||||
options.end?.(event)
|
||||
}
|
||||
|
||||
on(element, 'mousedown', function (event) {
|
||||
const downFn = function (event: Event) {
|
||||
if (isDragging) return
|
||||
event.preventDefault()
|
||||
document.onselectstart = () => false
|
||||
document.ondragstart = () => false
|
||||
on(document, 'mousemove', moveFn)
|
||||
on(document, 'mouseup', upFn)
|
||||
on(document, 'touchmove', moveFn)
|
||||
on(document, 'touchend', upFn)
|
||||
|
||||
isDragging = true
|
||||
|
||||
options.start?.(event)
|
||||
})
|
||||
}
|
||||
|
||||
on(element, 'mousedown', downFn)
|
||||
on(element, 'touchstart', downFn)
|
||||
}
|
||||
|
@ -234,3 +234,22 @@ export const getOffsetTopDistance = (
|
||||
}
|
||||
|
||||
export const stop = (e: Event) => e.stopPropagation()
|
||||
|
||||
export const getClientXY = (event: MouseEvent | TouchEvent) => {
|
||||
let clientX: number
|
||||
let clientY: number
|
||||
if (event.type === 'touchend') {
|
||||
clientY = (event as TouchEvent).changedTouches[0].clientY
|
||||
clientX = (event as TouchEvent).changedTouches[0].clientX
|
||||
} else if (event.type.startsWith('touch')) {
|
||||
clientY = (event as TouchEvent).touches[0].clientY
|
||||
clientX = (event as TouchEvent).touches[0].clientX
|
||||
} else {
|
||||
clientY = (event as MouseEvent).clientY
|
||||
clientX = (event as MouseEvent).clientX
|
||||
}
|
||||
return {
|
||||
clientX,
|
||||
clientY,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user