UNPKG

vuetify

Version:

Vue.js 2 Semantic Component Framework

214 lines (187 loc) 6.11 kB
export default { data () { return { hasChanged: false } }, methods: { genBody () { const children = [this.genHand(this.selectingHour ? 'hour' : 'minute')] const data = { 'class': 'picker--time__clock', on: { mousedown: this.onMouseDown, mouseup: this.onMouseUp, mouseleave: () => { this.isDragging && this.onMouseUp() }, touchstart: this.onMouseDown, touchend: this.onMouseUp, mousemove: this.onDragMove, touchmove: this.onDragMove }, key: this.selectingHour ? 'hour' : 'minute', ref: 'clock' } this.selectingHour && children.push(this.genHours()) || children.push(this.genMinutes()) if (this.scrollable) { data.on.wheel = e => { e.preventDefault() const diff = e.wheelDelta > 0 ? 1 : -1 const changing = this.selectingHour ? 'changeHour' : 'changeMinute' this[changing](diff) } } return this.$createElement('div', { 'class': 'picker__body' }, [ this.$createElement('transition', { props: { name: 'fade-transition', mode: 'out-in' } }, [ this.$createElement('div', data, children) ]) ]) }, genHand (type) { const scale = this.is24hrAfter12 ? 'scaleY(0.6)' : '' return [this.$createElement('div', { staticClass: 'picker--time__clock-hand', 'class': this.addBackgroundColorClassChecks({ [type]: true }), style: { transform: `rotate(${this.clockHand}deg) ${scale}` } })] }, genHours () { let hours = this.is24hr ? 24 : 12 const children = [] let start = 0 if (hours === 12) { hours++ start = 1 } for (let i = start; i < hours; i++) { const classes = { 'active': i === this.hour, 'disabled': !this.isAllowed('hour', i) } children.push(this.$createElement('span', { 'class': this.addBackgroundColorClassChecks(classes, i === this.hour ? 'computedColor' : null), style: this.getTransform(i), domProps: { innerHTML: `<span>${i}</span>` } })) } return children }, genMinutes () { const children = [] for (let i = 0; i < 60; i = i + 5) { let num = i if (num < 10) num = `0${num}` if (num === 60) num = '00' const classes = { 'active': num.toString() === this.minute.toString(), 'disabled': !this.isAllowed('minute', i) } children.push(this.$createElement('span', { 'class': this.addBackgroundColorClassChecks(classes, num.toString() === this.minute.toString() ? 'computedColor' : null), style: this.getTransform(i), domProps: { innerHTML: `<span>${num}</span>` } })) } return children }, getTransform (i) { const { x, y } = this.getPosition(i) return { transform: `translate(${x}px, ${y}px)` } }, getPosition (i) { const radiusPercentage = this.selectingHour && this.is24hr && i >= 12 ? 0.5 : 0.8 const r = this.radius * radiusPercentage i = this.selectingHour && this.is24hr ? i % 12 : i return { x: Math.round(Math.sin(i * this.degrees) * r), y: Math.round(-Math.cos(i * this.degrees) * r) } }, changeHour (time) { let range = this.generateRange('hour', this.hour) time < 0 && (range = range.reverse().slice(1)) this.hour = range.find((h) => { return this.allowedHours ? this.isAllowed('hour', h) : true }) return true }, changeMinute (time) { const current = Number(this.minute) let range = this.generateRange('minute', current) time < 0 && (range = range.reverse().slice(1)) const minute = range.find((m) => { return this.allowedMinutes ? this.isAllowed('minute', m) : true }) this.minute = minute < 10 ? `0${minute}` : minute return true }, onMouseDown (e) { e.preventDefault() this.isDragging = true this.onDragMove(e) }, onMouseUp () { this.isDragging = false !this.selectingHour && this.autosave && this.save() if (this.hasChanged) { this.selectingHour = false this.hasChanged = false } }, onDragMove (e) { e.preventDefault() if (!this.isDragging && e.type !== 'click') return const rect = this.$refs.clock.getBoundingClientRect() const center = { x: rect.width / 2, y: 0 - rect.width / 2 } const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX const coords = { y: rect.top - clientY, x: clientX - rect.left } const selecting = this.selectingHour ? 'hour' : 'minute' let value = Math.round(this.angle(center, coords) / this.degreesPerUnit) if (this.selectingHour && this.is24hr) { const insideClick = this.euclidean(center, coords) / this.radius < 0.65 value = insideClick ? value + 12 : value // Necessary to fix edge case when selecting left part of 0 and 12 value = this.angle(center, coords) >= 345 ? (value + 12) % 24 : value } if (this.isAllowed(selecting, value)) { this[selecting] = value this.hasChanged = true } }, euclidean (p0, p1) { const dx = Math.abs(p1.x - p0.x) const dy = Math.abs(p1.y - p0.y) return Math.sqrt(dx * dx + dy * dy) }, angle (center, p1) { var p0 = { x: center.x, y: center.y + Math.sqrt( Math.abs(p1.x - center.x) * Math.abs(p1.x - center.x) + Math.abs(p1.y - center.y) * Math.abs(p1.y - center.y)) } const value = 2 * Math.atan2(p1.y - p0.y, p1.x - p0.x) return Math.abs(value * 180 / Math.PI) } } }