-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.tsx
128 lines (125 loc) · 4.79 KB
/
index.tsx
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { Form, InputNumber } from 'antd';
import { HSLColor, rgb } from 'd3-color';
import React from 'react';
import { RgbaColorPicker } from 'react-colorful';
import { colorToLinearGradient, LinearGradientConvertOptions } from "color-gradient-converter";
import './style.less';
export const defaultTransformParams: LinearGradientConvertOptions = {
angle: 135,
colorStopTransformTargets: []
};
interface ColorGradientState {
backgroundColor: string;
backgroundblur: number;
borderColor: string;
borderWidth: number;
borderRadius: number;
transformParams: LinearGradientConvertOptions;
}
export class ColorGradient extends React.Component<unknown, ColorGradientState> {
constructor(props: unknown) {
super(props);
this.state = {
backgroundColor: 'rgba(45, 85, 170, 1)',
borderColor: 'rgba(0, 210, 255, 1)',
backgroundblur: 3,
borderWidth: 2,
borderRadius: 4,
transformParams: Object.assign(defaultTransformParams, {}),
};
}
render() {
const { backgroundColor, transformParams, backgroundblur, borderColor, borderWidth, borderRadius } = this.state;
const backgroundRgb = rgb(backgroundColor);
const borderRgb = rgb(borderColor);
const transformFn = (baseColor: HSLColor, transformTarget: HSLColor) => {
const target = transformTarget;
target.opacity = Number((baseColor.opacity * target.opacity).toFixed(2));
return target;
}
const borderGradient = `${colorToLinearGradient(borderColor, {
...transformParams,
colorStopTransformTargets: [
{ opacity: 0.1, transformFn },
{ opacity: 0.6, transformFn },
{ opacity: 0.2, transformFn },
{ opacity: 0.2, transformFn },
{ opacity: 0.6, transformFn },
{ opacity: 0.1, transformFn },
],
})} 10`;
const backgroundGradient = colorToLinearGradient(backgroundColor, {
...transformParams,
colorStopTransformTargets: [
{ opacity: 0.4, transformFn },
{ opacity: 0.2, transformFn, markPercent: '25%' },
{ opacity: 0.1, transformFn },
],
});
return (
<div style={{ padding: 10 }} className="color-gradient">
<div className="basic-color">
<div className="gradient-params">
<div style={{ padding: 10 }}>
background: <span>{backgroundColor}</span>
<RgbaColorPicker
color={{ r: backgroundRgb.r, g: backgroundRgb.g, b: backgroundRgb.b, a: backgroundRgb.opacity }}
onChange={c => this.setState({ backgroundColor: `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a || 0.01})` })}
/>
<Form style={{ padding: 10 }} layout="inline">
<Form.Item initialValue={transformParams.angle} name="angle" label="angle">
<InputNumber
min={-180}
max={180}
onChange={e => this.setState({ transformParams: Object.assign(transformParams, { angle: e }) })}
/>
</Form.Item>
<Form.Item initialValue={backgroundblur} name="blur" label="blur">
<InputNumber
min={1}
onChange={e => this.setState({ backgroundblur: e as number })}
/>
</Form.Item>
</Form>
</div>
<div style={{ padding: 10 }}>
border: <span>{borderColor}</span>
<RgbaColorPicker
color={{ r: borderRgb.r, g: borderRgb.g, b: borderRgb.b, a: borderRgb.opacity }}
onChange={c => this.setState({ borderColor: `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a || 0.01})` })}
/>
<Form style={{ padding: 10 }} layout="inline">
<Form.Item initialValue={borderWidth} name="borderWidth" label="borderWidth">
<InputNumber
min={1}
onChange={e => this.setState({ borderWidth: e as number })}
/>
</Form.Item>
<Form.Item initialValue={borderRadius} name="borderRadius" label="borderRadius">
<InputNumber
min={1}
onChange={e => this.setState({ borderRadius: e as number })}
/>
</Form.Item>
</Form>
</div>
</div>
</div>
<div className="gradient-preview">
<div
style={{
backdropFilter: `blur(${backgroundblur}px)`,
borderWidth,
borderStyle: `solid`,
borderRadius,
clipPath: `inset(0 round ${borderRadius}px)`,
borderImage: borderGradient,
background: backgroundGradient,
}}
className="gradient-grid"
/>
</div>
</div>
);
}
}