bklLiudl
2024-05-25 484e5129e4c9a671c5660a556a24bd306f1fdd9b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<template>
    <div
        :class="[prefixCls + '-hue']"
        tabindex="0"
        @click="$el.focus()"
        @keydown.esc="handleEscape"
        @keydown.left="handleLeft"
        @keydown.right="handleRight"
        @keydown.up="handleUp"
        @keydown.down="handleDown"
    >
        <div
            ref="container"
            :class="[prefixCls + '-hue-container']"
            @mousedown="handleMouseDown"
            @touchmove="handleChange"
            @touchstart="handleChange">
            <div
                :style="{top: 0, left: `${percent}%`}"
                :class="[prefixCls + '-hue-pointer']">
                <div :class="[prefixCls + '-hue-picker']"></div>
            </div>
        </div>
    </div>
</template>
 
<script>
import HASMixin from './hsaMixin';
import Prefixes from './prefixMixin';
import {clamp} from './utils';
 
export default {
    name: 'Hue',
 
    mixins: [HASMixin, Prefixes],
 
    data() {
        const normalStep = 1 / 360 * 25;
        const jumpStep = 20 * normalStep;
 
        return {
            left: -normalStep,
            right: normalStep,
            up: jumpStep,
            down: -jumpStep,
            powerKey: 'shiftKey',
            percent: clamp(this.value.hsl.h * 100 / 360, 0, 100),
        };
    },
 
    watch: {
        value () {
            this.percent = clamp(this.value.hsl.h * 100 / 360, 0, 100);
        }
    },
 
    methods: {
        change(percent) {
            this.percent = clamp(percent, 0, 100);
 
            const {h, s, l, a} = this.value.hsl;
            const newHue = clamp(percent / 100 * 360, 0, 360);
 
            if (h !== newHue) {
                this.$emit('change', {h: newHue, s, l, a, source: 'hsl'});
            }
        },
        handleSlide(e, direction) {
            e.preventDefault();
            e.stopPropagation();
 
            if (e[this.powerKey]) {
                this.change(direction < 0 ? 0 : 100);
                return;
            }
 
            this.change(this.percent + direction);
        },
        handleChange(e) {
            e.preventDefault();
            e.stopPropagation();
 
            const left = this.getLeft(e);
 
            if (left < 0) {
                this.change(0);
                return;
            }
 
            const {clientWidth} = this.$refs.container;
 
            if (left > clientWidth) {
                this.change(100);
                return;
            }
 
            this.change(left * 100 / clientWidth);
        },
    },
};
</script>