@dingdaoos/lucid-utils
Version:
Lucid utils
128 lines (115 loc) • 3.51 kB
text/typescript
import { dragEvent } from '../../utils'
import { globalClick, getRect } from '../../utils'
interface Options<T> {
elWrapper: HTMLElement
elHandle: HTMLElement
elDots: HTMLElement
damperList: number[]
value: number
adapter: T
}
// damper class
class DamperDragger<T> {
private elWrapper: HTMLElement
private elHandle: HTMLElement
private elDots: HTMLElement
private damperList: number[]
private value: number
private index: number
private height: number
private startTop: number
private adapter: any
private dampersY: number[]
private fragment: number
constructor(options: Options<T>) {
const rect = getRect(options.elWrapper)
this.elWrapper = options.elWrapper
this.elHandle = options.elHandle
this.elDots = options.elDots
this.damperList = options.damperList
const _value = this.damperList.find(item => item === options.value)
this.value = _value || this.damperList[0]
this.index = this.damperList.findIndex(item => item === this.value)
this.height = rect.height - 24
this.startTop = 0
this.adapter = options.adapter
this.dampersY = this.getDampersY()
this.fragment = (this.dampersY[1] - this.dampersY[0]) / 2
this.bindEvent()
this.setTop()
this.dragInit()
globalClick((e: MouseEvent & { path: Node[] } ) => {
if (this.elWrapper?.parentNode && !e.path.includes(this.elWrapper.parentNode)) {
this.adapter.toggleBar(false)
}
})
}
bindEvent() {
this.elDots && this.elDots.addEventListener('click', (e: MouseEvent | Event) => {
if ((e?.target as HTMLElement).tagName === 'SPAN') {
const value: number = Number((e.target as HTMLElement).getAttribute('data-damp'))
this.index = this.damperList.findIndex(item => item === value)
this.setTop()
}
})
}
// set damper top value, and emit value
setTop() {
this.startTop = (this.index / (this.damperList.length - 1)) * this.height
let _top = this.startTop
_top = Math.max(_top, 0)
_top = Math.min(_top, this.height)
if (this.elHandle) this.elHandle.style.top = `${_top}px`
this.adapter.emitValue('input', this.damperList[this.index])
this.adapter.emitValue('change', this.damperList[this.index])
}
// get all damper y
getDampersY() {
const res: number[] = []
if (this.elDots)
Array.from(this.elDots.childNodes).filter((item: any) => item.nodeType === 1).forEach(item => {
res.push(getRect(item).y)
})
return res
}
// get damper top
getTop() {
return this.elHandle ? parseInt(this.elHandle.style.top) : 0
}
// init drag event
dragInit() {
const dragConfig = {
dragMove: (e: MouseEvent) => {
this.dragMove(e)
},
dragStart: (e: MouseEvent) => {
this.dragStart()
},
dragStop: (e: MouseEvent) => {
this.dragStop()
}
}
dragEvent(this.elHandle, dragConfig)
}
// drag start handler
dragStart() {
this.startTop = this.getTop()
}
// drag event handler
dragMove(e: MouseEvent) {
const y = e.clientY
const damperY = this.dampersY[this.index]
const len = this.damperList.length
if (y >= damperY + this.fragment) {
this.index = this.index >= len - 2 ? len - 1 : this.index + 1
} else if (y <= damperY - this.fragment) {
this.index = this.index <= 1 ? 0 : this.index - 1
}
this.setTop()
}
// drag stop handler
dragStop() {
this.setTop()
}
}
export default DamperDragger