UNPKG

3.6 kBPlain TextView Raw
1<template>
2 <section>
3 <svg
4 viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" class="z-range-bar"
5 ref="bar"
6 @click.stop="bar">
7 <circle r="52" cx="50" cy="50" :style="[styles]"></circle>
8 </svg>
9 <svg
10 xmlns="http://www.w3.org/2000/svg" class="z-range-bar-bar"
11 :style="circleStyle"
12 @touchstart="drag = true"
13 @touchmove.stop="handleBar"
14 @touchend="drag = false"
15 @mousedown="drag = true"
16 @mousemove.stop="handleBar"
17 @mouseup="drag = false">
18 <circle r="8" cx="20" cy="20" class="z-range-bar-handlebar"></circle>
19 </svg>
20 </section>
21</template>
22
23<script>
24export default {
25 name: 'z-knob',
26 props: {
27 qty: {
28 type: [Number]
29 },
30 min: {
31 type: [Number]
32 },
33 max: {
34 type: [Number]
35 },
36 pos: {
37 type: [String]
38 }
39 },
40 data () {
41 return {
42 componentType: this.$options.name,
43 drag: false,
44 angle: 0,
45 prevAngle: 0
46 }
47 },
48 computed: {
49 position () {
50 const diameter = this.$zircle.getComponentWidth(this.$parent.size) / 2
51 return {
52 X: (diameter - 3) * Math.cos(this.angle * (Math.PI / 180)),
53 Y: (diameter - 3) * Math.sin(this.angle * (Math.PI / 180)),
54 arc: (Math.PI * 100) * ((this.angle - 360) / 360)
55 }
56 },
57 styles () {
58 const circleLength = 2 * Math.PI * 50
59 return {
60 transformOrigin: '50% 50%',
61 transform: 'rotate(0deg)',
62 strokeDasharray: circleLength,
63 strokeDashoffset: -this.position.arc,
64 strokeWidth: 11
65 }
66 },
67 circleStyle () {
68 return {
69 transformOrigin: '50% 50%',
70 transform: 'translate3d(' + this.position.X + 'px, ' + this.position.Y + 'px, 0px)'
71 }
72 }
73 },
74 methods: {
75 bar (e) {
76 e = e.changedTouches ? e.changedTouches[0] : e
77 const dimensions = this.$refs.bar.getBoundingClientRect()
78 const centerx = (dimensions.width / 2) + dimensions.left
79 const centery = (dimensions.height / 2) + dimensions.top
80 const posx = e.pageX
81 const posy = e.pageY
82 const deltay = centery - posy
83 const deltax = centerx - posx
84 let tangle = Math.atan2(deltay, deltax) * (180 / Math.PI)
85 tangle -= 180
86 tangle = Math.round(tangle)
87 if (tangle < 0) tangle = 360 + tangle
88 let prevAngle = Math.round(this.angle)
89 const id = setInterval(() => {
90 if (prevAngle > tangle) {
91 prevAngle--
92 } else if (prevAngle < tangle) {
93 prevAngle++
94 } else {
95 clearInterval(id)
96 }
97 this.angle = prevAngle
98 this.$emit('update:qty', Math.round((prevAngle / 360) * (this.max - this.min)) + this.min)
99 }, 0)
100 },
101 handleBar (e) {
102 if (this.drag === true) {
103 e = e.changedTouches ? e.changedTouches[0] : e
104 const dimensions = this.$refs.bar.getBoundingClientRect()
105 const centerx = (dimensions.width / 2) + dimensions.left
106 const centery = (dimensions.height / 2) + dimensions.top
107 const posx = e.pageX
108 const posy = e.pageY
109 const deltay = centery - posy
110 const deltax = centerx - posx
111 let tangle = Math.atan2(deltay, deltax) * (180 / Math.PI)
112 tangle -= 180
113 tangle = Math.round(tangle)
114 if (tangle < 0) tangle = 360 + tangle
115 this.angle = tangle
116 this.$emit('update:qty', Math.round((tangle / 360) * (this.max - this.min)) + this.min)
117 }
118 }
119 },
120 mounted () {
121 this.angle = Math.round(((this.qty - this.min) * 360) / (this.max - this.min))
122 }
123}
124</script>