@ledvance/base 1.3.65 → 1.3.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/ColorAdjustView.tsx +11 -77
- package/src/components/ColorTempAdjustView.tsx +6 -75
- package/src/composeLayout.tsx +1 -1
- package/src/models/TuyaApi.ts +0 -132
- package/src/models/modules/NativePropsSlice.tsx +2 -13
- package/src/components/rect-color-and-bright-picker/ColourPicker.tsx +0 -266
- package/src/components/rect-color-and-bright-picker/RectPicker.tsx +0 -398
- package/src/components/rect-color-and-bright-picker/Slider.tsx +0 -468
- package/src/components/rect-color-and-bright-picker/Thumb.tsx +0 -78
- package/src/components/rect-color-and-bright-picker/WhitePicker.tsx +0 -400
- package/src/components/rect-color-and-bright-picker/brightness-icons/index.ts +0 -8
- package/src/components/rect-color-and-bright-picker/index.tsx +0 -5
- package/src/components/rect-color-and-bright-picker/res/index.ts +0 -3
- package/src/components/rect-color-and-bright-picker/res/thumb-mask@2x.png +0 -0
- package/src/components/rect-color-and-bright-picker/res/thumb-mask@3x.png +0 -0
- package/src/components/rect-color-and-bright-picker/utils/color.ts +0 -73
- package/src/components/rect-color-and-bright-picker/utils/storage.ts +0 -97
package/package.json
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
import {View} from 'react-native'
|
|
2
|
-
import React
|
|
2
|
+
import React from 'react'
|
|
3
3
|
import LdvColorSlider from './ldvColorSlider'
|
|
4
4
|
import {hex2Hsv, hsv2Hex} from '../utils'
|
|
5
5
|
import LdvPresetView from './ldvPresetView'
|
|
6
6
|
import LdvSaturation from './ldvSaturation'
|
|
7
7
|
import LdvColorBrightness from './ldvColorBrightness'
|
|
8
8
|
import I18n from '../i18n/index'
|
|
9
|
-
import RectColorAndBrightPicker from './rect-color-and-bright-picker'
|
|
10
|
-
import {Utils} from "tuya-panel-kit";
|
|
11
|
-
import {useReactive, useUpdateEffect} from "ahooks";
|
|
12
|
-
import {useNewPalette} from "../models/modules/NativePropsSlice";
|
|
13
|
-
|
|
14
|
-
const cx = Utils.RatioUtils.convertX
|
|
15
|
-
const scaleUp = (value) => value * 10
|
|
16
|
-
const scaleDown = (value) => Math.round(value / 10)
|
|
17
|
-
const width = Utils.RatioUtils.width - cx(80)
|
|
18
9
|
|
|
19
10
|
export interface ColorAdjustViewProps {
|
|
20
11
|
h: number
|
|
@@ -28,59 +19,7 @@ export interface ColorAdjustViewProps {
|
|
|
28
19
|
onHSVChangeComplete: (h: number, s: number, v: number) => void
|
|
29
20
|
}
|
|
30
21
|
|
|
31
|
-
const
|
|
32
|
-
const { h = 0, s = 100, v = 100, minBrightness = 10, onHSVChange, onHSVChangeComplete } = props
|
|
33
|
-
const state = useReactive({
|
|
34
|
-
hue: h,
|
|
35
|
-
saturation: scaleUp(s),
|
|
36
|
-
value: scaleUp(v),
|
|
37
|
-
moving: false
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
useUpdateEffect(() => {
|
|
41
|
-
if (!state.moving) {
|
|
42
|
-
state.hue = h
|
|
43
|
-
state.saturation = scaleUp(s)
|
|
44
|
-
state.value = scaleUp(v)
|
|
45
|
-
}
|
|
46
|
-
}, [h, s, v])
|
|
47
|
-
|
|
48
|
-
const handleMove = useCallback((v) => {
|
|
49
|
-
onHSVChange?.(v.hue, scaleDown(v.saturation), scaleDown(v.value))
|
|
50
|
-
}, [onHSVChange])
|
|
51
|
-
|
|
52
|
-
const handleComplete = useCallback((v) => {
|
|
53
|
-
onHSVChangeComplete?.(v.hue, scaleDown(v.saturation), scaleDown(v.value))
|
|
54
|
-
state.moving = false
|
|
55
|
-
}, [onHSVChangeComplete])
|
|
56
|
-
|
|
57
|
-
const { hue, saturation, value } = state;
|
|
58
|
-
const hsv = { hue, saturation, value };
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<View style={{justifyContent: 'center', alignItems: 'center'}}>
|
|
62
|
-
<View style={{
|
|
63
|
-
width: width,
|
|
64
|
-
height: cx(200),
|
|
65
|
-
borderRadius: cx(10),
|
|
66
|
-
borderColor: '#eeeeef',
|
|
67
|
-
borderWidth: 1,
|
|
68
|
-
overflow: 'hidden'
|
|
69
|
-
}}>
|
|
70
|
-
<RectColorAndBrightPicker.ColourPicker
|
|
71
|
-
value={hsv}
|
|
72
|
-
brightOption={{min: minBrightness, minPercent: minBrightness ? 1 : 0}}
|
|
73
|
-
onGrant={() => state.moving = true}
|
|
74
|
-
onMove={handleMove}
|
|
75
|
-
onRelease={handleComplete}
|
|
76
|
-
onPress={handleComplete}
|
|
77
|
-
/>
|
|
78
|
-
</View>
|
|
79
|
-
</View>
|
|
80
|
-
)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const OldColorPicker = React.memo((props: ColorAdjustViewProps) => {
|
|
22
|
+
const ColorAdjustView = (props: ColorAdjustViewProps) => {
|
|
84
23
|
return (
|
|
85
24
|
<View>
|
|
86
25
|
<LdvColorSlider
|
|
@@ -103,14 +42,14 @@ const OldColorPicker = React.memo((props: ColorAdjustViewProps) => {
|
|
|
103
42
|
}
|
|
104
43
|
}}/>
|
|
105
44
|
{!props.hideSat && <LdvSaturation
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
45
|
+
value={props.s}
|
|
46
|
+
minSaturation={props.minSaturation}
|
|
47
|
+
onValueChange={s => {
|
|
48
|
+
props.onHSVChange && props.onHSVChange(props.h, s, props.v)
|
|
49
|
+
}}
|
|
50
|
+
onSlidingComplete={s => {
|
|
51
|
+
props.onHSVChangeComplete(props.h, s, props.v)
|
|
52
|
+
}}/>}
|
|
114
53
|
<LdvColorBrightness
|
|
115
54
|
minBrightness={props.minBrightness}
|
|
116
55
|
value={props.v}
|
|
@@ -122,11 +61,6 @@ const OldColorPicker = React.memo((props: ColorAdjustViewProps) => {
|
|
|
122
61
|
}}/>
|
|
123
62
|
</View>
|
|
124
63
|
)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
const ColorAdjustView = (props: ColorAdjustViewProps) => {
|
|
128
|
-
const newPalette = useNewPalette()
|
|
129
|
-
return newPalette ? <NewColorPicker {...props} /> : <OldColorPicker {...props} />
|
|
130
64
|
}
|
|
131
65
|
|
|
132
|
-
export default ColorAdjustView
|
|
66
|
+
export default ColorAdjustView
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {View} from 'react-native'
|
|
2
|
-
import React
|
|
2
|
+
import React from 'react'
|
|
3
3
|
import LdvColorSlider from './ldvColorSlider'
|
|
4
4
|
import Spacer from './Spacer'
|
|
5
5
|
import LdvPresetView from './ldvPresetView'
|
|
@@ -7,17 +7,13 @@ import LdvSlider from './ldvSlider'
|
|
|
7
7
|
import {Utils} from 'tuya-panel-kit'
|
|
8
8
|
import I18n from '../i18n/index'
|
|
9
9
|
import {cctToColor} from '../utils/cctUtils'
|
|
10
|
-
import
|
|
11
|
-
import {useReactive, useUpdateEffect} from 'ahooks'
|
|
12
|
-
import { useNewPalette } from 'models/modules/NativePropsSlice'
|
|
10
|
+
import ThemeType from '../config/themeType'
|
|
13
11
|
|
|
14
12
|
const {convertX: cx} = Utils.RatioUtils
|
|
15
|
-
|
|
16
|
-
const scaleUp = (value: number) => value * 10;
|
|
17
|
-
const scaleDown = (value: number) => Math.round(value / 10);
|
|
18
|
-
const width = Utils.RatioUtils.width - cx(80);
|
|
13
|
+
const { withTheme } = Utils.ThemeUtils
|
|
19
14
|
|
|
20
15
|
export interface ColorTempAdjustViewProps {
|
|
16
|
+
theme?: ThemeType
|
|
21
17
|
colorTemp: number
|
|
22
18
|
brightness: number
|
|
23
19
|
minBrightness?: number
|
|
@@ -29,67 +25,7 @@ export interface ColorTempAdjustViewProps {
|
|
|
29
25
|
onBrightnessChangeComplete: (brightness: number) => void
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
const
|
|
33
|
-
const {
|
|
34
|
-
colorTemp = 0,
|
|
35
|
-
brightness = 100,
|
|
36
|
-
isSupportTemperature,
|
|
37
|
-
onCCTChange,
|
|
38
|
-
onCCTChangeComplete,
|
|
39
|
-
onBrightnessChange,
|
|
40
|
-
onBrightnessChangeComplete,
|
|
41
|
-
} = props
|
|
42
|
-
const state = useReactive({
|
|
43
|
-
temperature: scaleUp(colorTemp),
|
|
44
|
-
brightness: scaleUp(brightness),
|
|
45
|
-
moving: false
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
useUpdateEffect(() => {
|
|
49
|
-
if (!state.moving) {
|
|
50
|
-
state.temperature = scaleUp(colorTemp)
|
|
51
|
-
state.brightness = scaleUp(brightness)
|
|
52
|
-
}
|
|
53
|
-
}, [colorTemp, brightness])
|
|
54
|
-
|
|
55
|
-
const handleMove = useCallback((v) => {
|
|
56
|
-
onCCTChange?.(scaleDown(v.temperature))
|
|
57
|
-
onBrightnessChange?.(scaleDown(v.brightness))
|
|
58
|
-
}, [onCCTChange, onBrightnessChange])
|
|
59
|
-
|
|
60
|
-
const handleComplete = useCallback((v) => {
|
|
61
|
-
onCCTChangeComplete?.(scaleDown(v.temperature))
|
|
62
|
-
onBrightnessChangeComplete?.(scaleDown(v.brightness))
|
|
63
|
-
state.moving = false
|
|
64
|
-
}, [onCCTChangeComplete, onBrightnessChangeComplete])
|
|
65
|
-
|
|
66
|
-
const { temperature, brightness: stateBrightness } = state
|
|
67
|
-
const white = { temperature, brightness: stateBrightness }
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<View style={{justifyContent: 'center', alignItems: 'center'}}>
|
|
71
|
-
<View style={{
|
|
72
|
-
width: width,
|
|
73
|
-
height: cx(isSupportTemperature? 200 : 50),
|
|
74
|
-
borderRadius: cx(10),
|
|
75
|
-
borderColor: '#eeeeef',
|
|
76
|
-
borderWidth: 1,
|
|
77
|
-
overflow: 'hidden'
|
|
78
|
-
}}>
|
|
79
|
-
<RectColorAndBrightPicker.WhitePicker
|
|
80
|
-
hideTemp={!isSupportTemperature}
|
|
81
|
-
value={white}
|
|
82
|
-
onGrant={() => state.moving = true}
|
|
83
|
-
onMove={handleMove}
|
|
84
|
-
onRelease={handleComplete}
|
|
85
|
-
onPress={handleComplete}
|
|
86
|
-
/>
|
|
87
|
-
</View>
|
|
88
|
-
</View>
|
|
89
|
-
)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
const OldColorTempPicker = React.memo((props: ColorTempAdjustViewProps) => {
|
|
28
|
+
const ColorTempAdjustView = (props: ColorTempAdjustViewProps) => {
|
|
93
29
|
return (
|
|
94
30
|
<View>
|
|
95
31
|
{props.isSupportTemperature &&
|
|
@@ -120,11 +56,6 @@ const OldColorTempPicker = React.memo((props: ColorTempAdjustViewProps) => {
|
|
|
120
56
|
onSlidingComplete={props.onBrightnessChangeComplete}/>}
|
|
121
57
|
</View>
|
|
122
58
|
)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const ColorTempAdjustView = (props: ColorTempAdjustViewProps) => {
|
|
126
|
-
const newPalette = useNewPalette()
|
|
127
|
-
return newPalette ? <NewColorTempPicker {...props} /> : <OldColorTempPicker {...props} />
|
|
128
59
|
}
|
|
129
60
|
|
|
130
|
-
export default ColorTempAdjustView
|
|
61
|
+
export default withTheme(ColorTempAdjustView)
|
package/src/composeLayout.tsx
CHANGED
|
@@ -132,7 +132,7 @@ const composeLayout = (component: React.ComponentType) => {
|
|
|
132
132
|
dispatch(setTimeZone(timeZone))
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
-
dispatch(setNewPalette(!!props.newPalette))
|
|
135
|
+
dispatch(setNewPalette(!!props.newPalette || true))
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
initReduxDeviceNativeProps(ldvDevInfo: LdvDevInfo) {
|
package/src/models/TuyaApi.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import {commonApi} from '@tuya/tuya-panel-api'
|
|
2
2
|
import { IGetDpResultByHourResponse, IGetDpResultByMonthResponse } from '@tuya/tuya-panel-api/lib/common/interface'
|
|
3
3
|
import {sendAppEvent} from "../api/native";
|
|
4
|
-
import {retryWithBackoff} from "../utils/index";
|
|
5
|
-
import {TYSdk} from "tuya-panel-kit";
|
|
6
4
|
|
|
7
5
|
export interface PagingResult<T> {
|
|
8
6
|
data: T
|
|
@@ -150,133 +148,3 @@ export async function getDpResultByHour(
|
|
|
150
148
|
}
|
|
151
149
|
}
|
|
152
150
|
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* 获取设备所有数据点记录(支持失败重试)
|
|
156
|
-
* @param commonApi API实例
|
|
157
|
-
* @param devId 设备ID
|
|
158
|
-
* @param dpIds 数据点ID,如 '19'
|
|
159
|
-
* @param sortType 排序方式
|
|
160
|
-
* @param retryOptions 重试选项
|
|
161
|
-
* @returns 所有数据点记录
|
|
162
|
-
*/
|
|
163
|
-
export async function getAllDpReportLogs(
|
|
164
|
-
devId: string,
|
|
165
|
-
dpIds: string[],
|
|
166
|
-
sortType: 'ASC' | 'DESC' = 'ASC',
|
|
167
|
-
retryOptions: {
|
|
168
|
-
maxRetries?: number;
|
|
169
|
-
initialDelay?: number;
|
|
170
|
-
maxDelay?: number;
|
|
171
|
-
backoffFactor?: number;
|
|
172
|
-
} = {}
|
|
173
|
-
): Promise<DpReportSataData[]> {
|
|
174
|
-
const limit = 100; // 每次请求的数据量
|
|
175
|
-
let offset = 1;
|
|
176
|
-
let hasNext = true;
|
|
177
|
-
const allDps: DpReportSataData[] = [];
|
|
178
|
-
|
|
179
|
-
while (hasNext) {
|
|
180
|
-
try {
|
|
181
|
-
// 使用重试函数包装API调用
|
|
182
|
-
const res: DpReportSataResData = await retryWithBackoff(
|
|
183
|
-
() => commonApi.statApi.getDpReportLog({
|
|
184
|
-
devId,
|
|
185
|
-
dpIds: dpIds.join(','),
|
|
186
|
-
offset,
|
|
187
|
-
limit,
|
|
188
|
-
sortType
|
|
189
|
-
}),
|
|
190
|
-
{
|
|
191
|
-
...retryOptions,
|
|
192
|
-
// 自定义判断哪些错误需要重试
|
|
193
|
-
shouldRetry: (error) => {
|
|
194
|
-
// 网络错误、超时错误或服务器错误(5xx)通常需要重试
|
|
195
|
-
const isNetworkError = error.name === 'NetworkError' ||
|
|
196
|
-
error.name === 'TimeoutError' ||
|
|
197
|
-
(error.response && error.response.status >= 500);
|
|
198
|
-
|
|
199
|
-
// 对于特定的业务错误码也可以在这里添加判断
|
|
200
|
-
return isNetworkError;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
allDps.push(...res.dps);
|
|
206
|
-
|
|
207
|
-
if (res.hasNext) {
|
|
208
|
-
offset += limit;
|
|
209
|
-
} else {
|
|
210
|
-
hasNext = false;
|
|
211
|
-
}
|
|
212
|
-
} catch (error) {
|
|
213
|
-
console.error('获取数据点记录失败,不再继续获取:', error);
|
|
214
|
-
hasNext = false;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return allDps;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export const saveDeviceExtInfo = async (devId: string, key: string, value: string): Promise<boolean> => {
|
|
222
|
-
try {
|
|
223
|
-
return await new Promise<any>((resolve, reject) => {
|
|
224
|
-
TYSdk.native.apiRNRequest(
|
|
225
|
-
{
|
|
226
|
-
v: "1.0",
|
|
227
|
-
postData: {
|
|
228
|
-
value: value,
|
|
229
|
-
key: key,
|
|
230
|
-
devId: devId
|
|
231
|
-
},
|
|
232
|
-
a: "tuya.m.solution.device.storage.save"
|
|
233
|
-
},
|
|
234
|
-
(success: any) => {
|
|
235
|
-
console.log('tuya.m.solution.device.storage.save success', success)
|
|
236
|
-
resolve(success)
|
|
237
|
-
},
|
|
238
|
-
(error: any) => {
|
|
239
|
-
console.log('tuya.m.solution.device.storage.save error', error)
|
|
240
|
-
reject(error)
|
|
241
|
-
}
|
|
242
|
-
)
|
|
243
|
-
})
|
|
244
|
-
} catch (error) {
|
|
245
|
-
console.log('saveDeviceExtInfo error', error)
|
|
246
|
-
return false
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export const getDeviceExtInfo = async (devId: string, key: string): Promise<string | null> => {
|
|
251
|
-
try {
|
|
252
|
-
const success = await new Promise<any>((resolve, reject) => {
|
|
253
|
-
TYSdk.native.apiRNRequest(
|
|
254
|
-
{
|
|
255
|
-
v: "1.0",
|
|
256
|
-
postData: {
|
|
257
|
-
"key": key,
|
|
258
|
-
"devId": devId
|
|
259
|
-
},
|
|
260
|
-
a: "tuya.m.solution.device.storage.get"
|
|
261
|
-
},
|
|
262
|
-
(success: any) => {
|
|
263
|
-
console.log('tuya.m.solution.device.storage.get success', success)
|
|
264
|
-
resolve(success)
|
|
265
|
-
},
|
|
266
|
-
(error: any) => {
|
|
267
|
-
console.log('tuya.m.solution.device.storage.get error', error)
|
|
268
|
-
reject(error)
|
|
269
|
-
}
|
|
270
|
-
)
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
let data = success
|
|
274
|
-
if (typeof success === 'string') {
|
|
275
|
-
data = JSON.parse(success)
|
|
276
|
-
}
|
|
277
|
-
return data.value
|
|
278
|
-
} catch (error) {
|
|
279
|
-
console.log('getDeviceExtInfo error', error)
|
|
280
|
-
return null
|
|
281
|
-
}
|
|
282
|
-
}
|
|
@@ -24,7 +24,6 @@ export interface NativeProps {
|
|
|
24
24
|
is24HourClock: boolean
|
|
25
25
|
timeZone: string
|
|
26
26
|
gestureControlValues: GestureControlType
|
|
27
|
-
newPalette?: boolean
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
interface FlagModeState {
|
|
@@ -88,8 +87,7 @@ const initialState: NativeProps = {
|
|
|
88
87
|
timeZone: 'Europe/Berlin',
|
|
89
88
|
gestureControlValues: {
|
|
90
89
|
isEnd: false
|
|
91
|
-
}
|
|
92
|
-
newPalette: false
|
|
90
|
+
}
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
// energy generation
|
|
@@ -190,9 +188,6 @@ const nativePropsSlice = createSlice({
|
|
|
190
188
|
keys.forEach(key => {
|
|
191
189
|
state.gestureControlValues[key] = action.payload[key]
|
|
192
190
|
})
|
|
193
|
-
},
|
|
194
|
-
setNewPalette(state, action: PayloadAction<boolean>) {
|
|
195
|
-
state.newPalette = action.payload
|
|
196
191
|
}
|
|
197
192
|
},
|
|
198
193
|
})
|
|
@@ -484,10 +479,6 @@ function useGestureControl<K extends keyof GestureControlType>(key: K): [Gesture
|
|
|
484
479
|
return [value]
|
|
485
480
|
}
|
|
486
481
|
|
|
487
|
-
const useNewPalette = () => {
|
|
488
|
-
return useSelector(store => store.ldvModules.newPalette)
|
|
489
|
-
}
|
|
490
|
-
|
|
491
482
|
export const useFanMaxSpeed = () => {
|
|
492
483
|
const { productId } = useDeviceInfo()
|
|
493
484
|
return fanProductList.includes(productId) ? 20 : 3
|
|
@@ -514,7 +505,6 @@ export const {
|
|
|
514
505
|
setTimeZone,
|
|
515
506
|
setEnergieverbrauch,
|
|
516
507
|
setGestureControlValues,
|
|
517
|
-
setNewPalette,
|
|
518
508
|
} = nativePropsSlice.actions
|
|
519
509
|
|
|
520
510
|
export {
|
|
@@ -541,6 +531,5 @@ export {
|
|
|
541
531
|
useTimeZoneCity,
|
|
542
532
|
useEnergieverbrauch,
|
|
543
533
|
useGestureControl,
|
|
544
|
-
useDeviceCategory
|
|
545
|
-
useNewPalette
|
|
534
|
+
useDeviceCategory
|
|
546
535
|
}
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { View, ViewStyle, StyleProp } from 'react-native';
|
|
4
|
-
import RectPicker, { ValidBound, Point, defaultProps as baseDefault } from './RectPicker';
|
|
5
|
-
import Slider, { IBrightOption } from './Slider';
|
|
6
|
-
import ColorUtils from './utils/color';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const rectGradientBg = [
|
|
10
|
-
{
|
|
11
|
-
colors: [
|
|
12
|
-
{ offset: '0%', stopColor: '#FF0000', stopOpacity: 1 },
|
|
13
|
-
{ offset: '8%', stopColor: '#FF7F00', stopOpacity: 1 },
|
|
14
|
-
{ offset: '20%', stopColor: '#FFFF00', stopOpacity: 1 },
|
|
15
|
-
{ offset: '25%', stopColor: '#7FFF00', stopOpacity: 1 },
|
|
16
|
-
{ offset: '33%', stopColor: '#00FF00', stopOpacity: 1 },
|
|
17
|
-
{ offset: '42%', stopColor: '#00FF7F', stopOpacity: 1 },
|
|
18
|
-
{ offset: '50%', stopColor: '#00FFFF', stopOpacity: 1 },
|
|
19
|
-
{ offset: '58%', stopColor: '#007FFF', stopOpacity: 1 },
|
|
20
|
-
{ offset: '66%', stopColor: '#0000FF', stopOpacity: 1 },
|
|
21
|
-
{ offset: '75%', stopColor: '#7F00FF', stopOpacity: 1 },
|
|
22
|
-
{ offset: '83%', stopColor: '#FF00FF', stopOpacity: 1 },
|
|
23
|
-
{ offset: '92%', stopColor: '#FF007F', stopOpacity: 1 },
|
|
24
|
-
{ offset: '100%', stopColor: '#FF0000', stopOpacity: 1 },
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
x2: '0%',
|
|
29
|
-
y2: '100%',
|
|
30
|
-
colors: [
|
|
31
|
-
{ offset: '0%', stopColor: '#fff', stopOpacity: 1 },
|
|
32
|
-
{ offset: '16%', stopColor: '#fff', stopOpacity: 0.9 },
|
|
33
|
-
{ offset: '100%', stopColor: '#fff', stopOpacity: 0 },
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
export interface IHsv {
|
|
39
|
-
hue: number;
|
|
40
|
-
saturation: number;
|
|
41
|
-
value: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const defaultProps = {
|
|
45
|
-
...baseDefault,
|
|
46
|
-
/**
|
|
47
|
-
* 值
|
|
48
|
-
*/
|
|
49
|
-
value: { hue: 0, saturation: 1000, value: 1000 } as IHsv,
|
|
50
|
-
/**
|
|
51
|
-
* 色度偏量
|
|
52
|
-
*/
|
|
53
|
-
hueOffset: 1,
|
|
54
|
-
/**
|
|
55
|
-
* 亮度配置
|
|
56
|
-
*/
|
|
57
|
-
brightOption: {} as IBrightOption,
|
|
58
|
-
/**
|
|
59
|
-
* 是否隐藏亮度调节
|
|
60
|
-
*/
|
|
61
|
-
hideBright: false,
|
|
62
|
-
/**
|
|
63
|
-
* 失去焦点时的亮度滑动条颜色
|
|
64
|
-
*/
|
|
65
|
-
lossSliderColor: 'rgba(255,255,255,0.4)',
|
|
66
|
-
/**
|
|
67
|
-
* 背景渐变配置
|
|
68
|
-
*/
|
|
69
|
-
bgs: rectGradientBg,
|
|
70
|
-
/**
|
|
71
|
-
* 滑动开始事件
|
|
72
|
-
* @param _v
|
|
73
|
-
* @param _option
|
|
74
|
-
*/
|
|
75
|
-
onGrant(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
76
|
-
/**
|
|
77
|
-
* 滑动过程事件
|
|
78
|
-
* @param _v
|
|
79
|
-
* @param _option
|
|
80
|
-
*/
|
|
81
|
-
onMove(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
82
|
-
/**
|
|
83
|
-
* 滑动结束事件
|
|
84
|
-
* @param _v
|
|
85
|
-
* @param _option
|
|
86
|
-
*/
|
|
87
|
-
onRelease(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
88
|
-
/**
|
|
89
|
-
* 点击事件
|
|
90
|
-
* @param _v
|
|
91
|
-
* @param _option
|
|
92
|
-
* @version ^0.3.0
|
|
93
|
-
*/
|
|
94
|
-
onPress(_v: any, _option?: { isChangeBright: boolean }) {},
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
type DefaultProps = Readonly<typeof defaultProps>;
|
|
98
|
-
|
|
99
|
-
type ColourProps = {
|
|
100
|
-
/**
|
|
101
|
-
* 组件的样式
|
|
102
|
-
*/
|
|
103
|
-
style?: StyleProp<ViewStyle>;
|
|
104
|
-
/**
|
|
105
|
-
* 颜色选择区的样式
|
|
106
|
-
*/
|
|
107
|
-
rectStyle?: StyleProp<ViewStyle>;
|
|
108
|
-
} & DefaultProps;
|
|
109
|
-
|
|
110
|
-
type IState = IHsv;
|
|
111
|
-
|
|
112
|
-
export default class ColourPicker extends Component<ColourProps, IState> {
|
|
113
|
-
static defaultProps: DefaultProps = defaultProps;
|
|
114
|
-
constructor(props: ColourProps) {
|
|
115
|
-
super(props);
|
|
116
|
-
this.state = { ...this.props.value };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// eslint-disable-next-line react/no-deprecated
|
|
120
|
-
componentWillReceiveProps(nextProps: ColourProps) {
|
|
121
|
-
if (!_.isEqual(nextProps.value, this.props.value)) {
|
|
122
|
-
this.setState({ ...nextProps.value });
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
shouldComponentUpdate(nextProps: ColourProps, nextState: IState) {
|
|
127
|
-
return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
onBrightGrant = () => {
|
|
131
|
-
const { hue, saturation, value } = this.state;
|
|
132
|
-
this.firPropsEvent(this.props.onGrant, { hue, saturation, value }, { isChangeBright: true });
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
onBrightMove = (value: number) => {
|
|
136
|
-
const { hue, saturation } = this.state;
|
|
137
|
-
this.firPropsEvent(this.props.onMove, { hue, saturation, value }, { isChangeBright: true });
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
onBrightRelease = (value: number) => {
|
|
141
|
-
const { hue, saturation } = this.state;
|
|
142
|
-
this.setState({ value });
|
|
143
|
-
this.firPropsEvent(this.props.onRelease, { hue, saturation, value }, { isChangeBright: true });
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
onBrightPress = (value: number) => {
|
|
147
|
-
const { hue, saturation } = this.state;
|
|
148
|
-
this.setState({ value });
|
|
149
|
-
this.firPropsEvent(this.props.onPress, { hue, saturation, value }, { isChangeBright: true });
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
coorToValue = ({ x, y }: Point, validBound: ValidBound) => {
|
|
153
|
-
const { hueOffset } = this.props;
|
|
154
|
-
const { width, height, x: validStartX, y: validStartY } = validBound;
|
|
155
|
-
const { value } = this.state;
|
|
156
|
-
let hue = Math.round(((x - validStartX) / width) * 360 + hueOffset) % 360;
|
|
157
|
-
const saturation = Math.round(((y - validStartY) / height) * 1000);
|
|
158
|
-
|
|
159
|
-
// hueOffset 不等于0时,最左边与最右边的值一样,为确保不会滑到最左边时跳到最右边
|
|
160
|
-
// 滑到最左边时,hue + 1;
|
|
161
|
-
if (hueOffset !== 0) {
|
|
162
|
-
if (Math.abs(x - validStartX) < 1) {
|
|
163
|
-
hue += 1;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return { hue, saturation, value };
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
valueToCoor = (hsv: IHsv, _origin: Point, validBound: ValidBound): Point => {
|
|
171
|
-
const { hueOffset } = this.props;
|
|
172
|
-
const { width, height, x: validStartX, y: validStartY } = validBound;
|
|
173
|
-
const { hue, saturation } = hsv;
|
|
174
|
-
let x = ((hue - hueOffset) / 360) * width;
|
|
175
|
-
if (x <= 0) {
|
|
176
|
-
x = width + x;
|
|
177
|
-
}
|
|
178
|
-
const y = (saturation / 1000) * height;
|
|
179
|
-
|
|
180
|
-
return { x: x + validStartX, y: y + validStartY };
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
valueToColor = (hsv: IHsv): string => {
|
|
184
|
-
const { hue, saturation, value } = hsv;
|
|
185
|
-
return ColorUtils.hsv2rgba(hue!, saturation, value) || 'transparent';
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
firPropsEvent(cb: (params?: any) => void, ...args: any[]) {
|
|
189
|
-
typeof cb === 'function' && cb(...args);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
handlePickerGrant = () => {
|
|
193
|
-
const { hue, saturation, value } = this.state;
|
|
194
|
-
this.firPropsEvent(this.props.onGrant, { hue, saturation, value });
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
handlePickerMove = (hsv: IHsv) => {
|
|
198
|
-
this.firPropsEvent(this.props.onMove, hsv);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
handlePickerRelease = (hsv: IHsv) => {
|
|
202
|
-
this.setState({ ...hsv });
|
|
203
|
-
this.firPropsEvent(this.props.onRelease, hsv);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
handlePickerPress = (hsv: IHsv) => {
|
|
207
|
-
this.setState({ ...hsv });
|
|
208
|
-
this.firPropsEvent(this.props.onPress, hsv);
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
initData = async () => {};
|
|
212
|
-
render() {
|
|
213
|
-
const {
|
|
214
|
-
style,
|
|
215
|
-
rectStyle,
|
|
216
|
-
brightOption,
|
|
217
|
-
lossShow,
|
|
218
|
-
lossSliderColor,
|
|
219
|
-
clickEnabled,
|
|
220
|
-
hideBright,
|
|
221
|
-
opacityAnimationValue,
|
|
222
|
-
opacityAnimationDuration,
|
|
223
|
-
...pickerProps
|
|
224
|
-
} = this.props;
|
|
225
|
-
const { hue, saturation, value: bright } = this.state;
|
|
226
|
-
const sliderProps: any = {};
|
|
227
|
-
if (lossShow) {
|
|
228
|
-
sliderProps.activeColor = lossSliderColor;
|
|
229
|
-
}
|
|
230
|
-
return (
|
|
231
|
-
<View style={[{ flex: 1 }, style]}>
|
|
232
|
-
<RectPicker
|
|
233
|
-
coorToValue={this.coorToValue}
|
|
234
|
-
valueToColor={this.valueToColor}
|
|
235
|
-
valueToCoor={this.valueToCoor}
|
|
236
|
-
value={{ hue, saturation, value: bright }}
|
|
237
|
-
lossShow={lossShow}
|
|
238
|
-
clickEnabled={clickEnabled}
|
|
239
|
-
opacityAnimationValue={opacityAnimationValue}
|
|
240
|
-
opacityAnimationDuration={opacityAnimationDuration}
|
|
241
|
-
{...pickerProps}
|
|
242
|
-
style={rectStyle}
|
|
243
|
-
onGrant={this.handlePickerGrant}
|
|
244
|
-
onMove={this.handlePickerMove}
|
|
245
|
-
onRelease={this.handlePickerRelease}
|
|
246
|
-
onPress={this.handlePickerPress}
|
|
247
|
-
initData={this.initData}
|
|
248
|
-
/>
|
|
249
|
-
{!hideBright && (
|
|
250
|
-
<Slider
|
|
251
|
-
opacityAnimationValue={opacityAnimationValue}
|
|
252
|
-
opacityAnimationDuration={opacityAnimationDuration}
|
|
253
|
-
{...brightOption}
|
|
254
|
-
{...sliderProps}
|
|
255
|
-
value={bright}
|
|
256
|
-
clickEnabled={clickEnabled}
|
|
257
|
-
onGrant={this.onBrightGrant}
|
|
258
|
-
onMove={this.onBrightMove}
|
|
259
|
-
onRelease={this.onBrightRelease}
|
|
260
|
-
onPress={this.onBrightPress}
|
|
261
|
-
/>
|
|
262
|
-
)}
|
|
263
|
-
</View>
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
}
|