-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathSlider.tsx
More file actions
114 lines (100 loc) · 2.85 KB
/
Slider.tsx
File metadata and controls
114 lines (100 loc) · 2.85 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { useRef } from 'react';
import useColorDrag from '../hooks/useColorDrag';
import type { HsbaColorType, TransformOffset } from '../interface';
import Palette from './Palette';
import { useEvent } from '@rc-component/util';
import { clsx } from 'clsx';
import { Color } from '../color';
import { calcOffset, calculateColor } from '../util';
import Gradient from './Gradient';
import Handler from './Handler';
import Transform from './Transform';
export interface BaseSliderProps {
prefixCls: string;
colors: { percent: number; color: string }[];
min: number;
max: number;
value: number;
disabled: boolean;
onChange: (value: number) => void;
onChangeComplete: (value: number) => void;
type: HsbaColorType;
color: Color;
}
const Slider: React.FC<BaseSliderProps> = props => {
const {
prefixCls,
colors,
disabled,
onChange,
onChangeComplete,
color,
type,
} = props;
const sliderRef = useRef<HTMLDivElement>(null);
const transformRef = useRef<HTMLDivElement>(null);
const colorRef = useRef<Color>(color);
const getValue = (c: Color) => {
return type === 'hue' ? c.getHue() : c.a * 100;
};
const onDragChange = useEvent((offsetValue: TransformOffset) => {
const calcColor = calculateColor({
offset: offsetValue,
targetRef: transformRef,
containerRef: sliderRef,
color,
type,
});
colorRef.current = calcColor;
onChange(getValue(calcColor));
});
const [offset, dragStartHandle] = useColorDrag({
color,
targetRef: transformRef,
containerRef: sliderRef,
calculate: () => calcOffset(color, type),
onDragChange,
onDragChangeComplete() {
onChangeComplete(getValue(colorRef.current));
},
direction: 'x',
disabledDrag: disabled,
});
const handleColor = React.useMemo(() => {
if (type === 'hue') {
const hsb = color.toHsb();
hsb.s = 1;
hsb.b = 1;
hsb.a = 1;
const lightColor = new Color(hsb);
return lightColor;
}
return color;
}, [color, type]);
// ========================= Gradient =========================
const gradientList = React.useMemo(
() => colors.map(info => `${info.color} ${info.percent}%`),
[colors],
);
// ========================== Render ==========================
return (
<div
ref={sliderRef}
className={clsx(`${prefixCls}-slider`, `${prefixCls}-slider-${type}`)}
onMouseDown={dragStartHandle}
onTouchStart={dragStartHandle}
>
<Palette prefixCls={prefixCls}>
<Transform x={offset.x} y={offset.y} ref={transformRef}>
<Handler
size="small"
color={handleColor.toHexString()}
prefixCls={prefixCls}
/>
</Transform>
<Gradient colors={gradientList} type={type} prefixCls={prefixCls} />
</Palette>
</div>
);
};
export default Slider;