1 | <template>
|
2 | <div class="el-color-hue-slider" :class="{ 'is-vertical': vertical }">
|
3 | <div class="el-color-hue-slider__bar" @click="handleClick" ref="bar"></div>
|
4 | <div class="el-color-hue-slider__thumb"
|
5 | :style="{
|
6 | left: thumbLeft + 'px',
|
7 | top: thumbTop + 'px'
|
8 | }"
|
9 | ref="thumb">
|
10 | </div>
|
11 | </div>
|
12 | </template>
|
13 |
|
14 | <script>
|
15 | import draggable from '../draggable';
|
16 |
|
17 | export default {
|
18 | name: 'el-color-hue-slider',
|
19 |
|
20 | props: {
|
21 | color: {
|
22 | required: true
|
23 | },
|
24 |
|
25 | vertical: Boolean
|
26 | },
|
27 |
|
28 | data() {
|
29 | return {
|
30 | thumbLeft: 0,
|
31 | thumbTop: 0
|
32 | };
|
33 | },
|
34 |
|
35 | computed: {
|
36 | hueValue() {
|
37 | const hue = this.color.get('hue');
|
38 | return hue;
|
39 | }
|
40 | },
|
41 |
|
42 | watch: {
|
43 | hueValue() {
|
44 | this.update();
|
45 | }
|
46 | },
|
47 |
|
48 | methods: {
|
49 | handleClick(event) {
|
50 | const thumb = this.$refs.thumb;
|
51 | const target = event.target;
|
52 |
|
53 | if (target !== thumb) {
|
54 | this.handleDrag(event);
|
55 | }
|
56 | },
|
57 |
|
58 | handleDrag(event) {
|
59 | const rect = this.$el.getBoundingClientRect();
|
60 | const { thumb } = this.$refs;
|
61 | let hue;
|
62 |
|
63 | if (!this.vertical) {
|
64 | let left = event.clientX - rect.left;
|
65 | left = Math.min(left, rect.width - thumb.offsetWidth / 2);
|
66 | left = Math.max(thumb.offsetWidth / 2, left);
|
67 |
|
68 | hue = Math.round((left - thumb.offsetWidth / 2) / (rect.width - thumb.offsetWidth) * 360);
|
69 | } else {
|
70 | let top = event.clientY - rect.top;
|
71 | top = Math.min(top, rect.height - thumb.offsetHeight / 2);
|
72 | top = Math.max(thumb.offsetHeight / 2, top);
|
73 |
|
74 | hue = Math.round((top - thumb.offsetHeight / 2) / (rect.height - thumb.offsetHeight) * 360);
|
75 | }
|
76 |
|
77 | this.color.set('hue', hue);
|
78 | },
|
79 |
|
80 | getThumbLeft() {
|
81 | if (this.vertical) return 0;
|
82 | const el = this.$el;
|
83 | const hue = this.color.get('hue');
|
84 |
|
85 | if (!el) return 0;
|
86 | const thumb = this.$refs.thumb;
|
87 | return Math.round(hue * (el.offsetWidth - thumb.offsetWidth / 2) / 360);
|
88 | },
|
89 |
|
90 | getThumbTop() {
|
91 | if (!this.vertical) return 0;
|
92 | const el = this.$el;
|
93 | const hue = this.color.get('hue');
|
94 |
|
95 | if (!el) return 0;
|
96 | const thumb = this.$refs.thumb;
|
97 | return Math.round(hue * (el.offsetHeight - thumb.offsetHeight / 2) / 360);
|
98 | },
|
99 |
|
100 | update() {
|
101 | this.thumbLeft = this.getThumbLeft();
|
102 | this.thumbTop = this.getThumbTop();
|
103 | }
|
104 | },
|
105 |
|
106 | mounted() {
|
107 | const { bar, thumb } = this.$refs;
|
108 |
|
109 | const dragConfig = {
|
110 | drag: (event) => {
|
111 | this.handleDrag(event);
|
112 | },
|
113 | end: (event) => {
|
114 | this.handleDrag(event);
|
115 | }
|
116 | };
|
117 |
|
118 | draggable(bar, dragConfig);
|
119 | draggable(thumb, dragConfig);
|
120 | this.update();
|
121 | }
|
122 | };
|
123 | </script>
|