UNPKG

vuetify

Version:

Vue.js 2 Semantic Component Framework

230 lines (204 loc) 6.48 kB
require('../../../src/stylus/components/_time-picker-clock.styl'); // Mixins import Colorable from '../../mixins/colorable'; import Themeable from '../../mixins/themeable'; // Utils import isValueAllowed from '../../util/isValueAllowed'; var outerRadius = 0.8; var innerRadius = 0.5; export default { name: 'v-time-picker-clock', mixins: [Colorable, Themeable], data: function data() { return { defaultColor: 'accent', inputValue: this.value, isDragging: false }; }, props: { allowedValues: { type: [Array, Object, Function], default: function _default() { return null; } }, double: Boolean, format: { type: Function, default: function _default(val) { return val; } }, max: { type: Number, require: true }, min: { type: Number, require: true }, scrollable: Boolean, rotate: { type: Number, default: 0 }, size: { type: [Number, String], default: 270 }, step: { type: Number, default: 1 }, value: { type: Number, required: true } }, computed: { count: function count() { return this.max - this.min + 1; }, roundCount: function roundCount() { return this.double ? this.count / 2 : this.count; }, degreesPerUnit: function degreesPerUnit() { return 360 / this.roundCount; }, degrees: function degrees() { return this.degreesPerUnit * Math.PI / 180; }, radius: function radius() { return this.size / 2; } }, watch: { value: function value(_value) { this.inputValue = _value; } }, methods: { wheel: function wheel(e) { e.preventDefault(); var value = this.value + Math.sign(e.wheelDelta || 1); this.update((value - this.min + this.count) % this.count + this.min); }, handScale: function handScale(value) { return this.double && value - this.min >= this.roundCount ? innerRadius / outerRadius : 1; }, isAllowed: function isAllowed(value) { return isValueAllowed(value, this.allowedValues); }, genValues: function genValues() { var children = []; for (var value = this.min; value <= this.max; value = value + this.step) { var classes = { active: value === this.value, disabled: !this.isAllowed(value) }; children.push(this.$createElement('span', { 'class': this.addBackgroundColorClassChecks(classes, value === this.value ? this.computedColor : null), style: this.getTransform(value), domProps: { innerHTML: '<span>' + this.format(value) + '</span>' } })); } return children; }, genHand: function genHand() { var scale = 'scaleY(' + this.handScale(this.value) + ')'; var angle = this.rotate + this.degreesPerUnit * (this.value - this.min); return this.$createElement('div', { staticClass: 'time-picker-clock__hand', 'class': this.addBackgroundColorClassChecks(), style: { transform: 'rotate(' + angle + 'deg) ' + scale } }); }, getTransform: function getTransform(i) { var _getPosition = this.getPosition(i), x = _getPosition.x, y = _getPosition.y; return { transform: 'translate(' + x + 'px, ' + y + 'px)' }; }, getPosition: function getPosition(value) { var radius = 0.83 * this.radius * this.handScale(value); var rotateRadians = this.rotate * Math.PI / 180; return { x: Math.round(Math.sin((value - this.min) * this.degrees + rotateRadians) * radius), y: Math.round(-Math.cos((value - this.min) * this.degrees + rotateRadians) * radius) }; }, onMouseDown: function onMouseDown(e) { e.preventDefault(); this.isDragging = true; this.onDragMove(e); }, onMouseUp: function onMouseUp() { this.isDragging = false; this.isAllowed(this.inputValue) && this.$emit('change', this.inputValue); }, onDragMove: function onDragMove(e) { e.preventDefault(); if (!this.isDragging && e.type !== 'click') return; var _$refs$clock$getBound = this.$refs.clock.getBoundingClientRect(), width = _$refs$clock$getBound.width, top = _$refs$clock$getBound.top, left = _$refs$clock$getBound.left; var _ref = 'touches' in e ? e.touches[0] : e, clientX = _ref.clientX, clientY = _ref.clientY; var center = { x: width / 2, y: -width / 2 }; var coords = { x: clientX - left, y: top - clientY }; var handAngle = Math.round(this.angle(center, coords) - this.rotate + 360) % 360; var insideClick = this.double && this.euclidean(center, coords) / this.radius < (outerRadius + innerRadius) / 2; var value = Math.round(handAngle / this.degreesPerUnit) + this.min + (insideClick ? this.roundCount : 0); // Necessary to fix edge case when selecting left part of max value if (handAngle >= 360 - this.degreesPerUnit / 2) { this.update(insideClick ? this.max : this.min); } else { this.update(value); } }, update: function update(value) { if (this.inputValue !== value && this.isAllowed(value)) { this.inputValue = value; this.$emit('input', value); } }, euclidean: function euclidean(p0, p1) { var dx = p1.x - p0.x; var dy = p1.y - p0.y; return Math.sqrt(dx * dx + dy * dy); }, angle: function angle(center, p1) { var value = 2 * Math.atan2(p1.y - center.y - this.euclidean(center, p1), p1.x - center.x); return Math.abs(value * 180 / Math.PI); } }, render: function render(h) { var _this = this; var data = { staticClass: 'time-picker-clock', style: { width: this.size + 'px', height: this.size + 'px' }, on: { mousedown: this.onMouseDown, mouseup: this.onMouseUp, mouseleave: function mouseleave() { return _this.isDragging && _this.onMouseUp(); }, touchstart: this.onMouseDown, touchend: this.onMouseUp, mousemove: this.onDragMove, touchmove: this.onDragMove }, ref: 'clock' }; this.scrollable && (data.on.wheel = this.wheel); return this.$createElement('div', data, [this.genHand(), this.genValues()]); } };