UNPKG

@dingdaoos/lucid-utils

Version:
128 lines (115 loc) 3.51 kB
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