@ledvance/base 1.3.68 → 1.3.72
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/localazy.json +8 -1
- package/package.json +1 -1
- package/src/api/native.ts +12 -11
- package/src/components/ColorAdjustView.tsx +77 -11
- package/src/components/ColorTempAdjustView.tsx +95 -6
- package/src/components/rect-color-and-bright-picker/ColourPicker.tsx +269 -0
- package/src/components/rect-color-and-bright-picker/RectPicker.tsx +448 -0
- package/src/components/rect-color-and-bright-picker/Slider.tsx +589 -0
- package/src/components/rect-color-and-bright-picker/Thumb.tsx +94 -0
- package/src/components/rect-color-and-bright-picker/WhitePicker.tsx +362 -0
- package/src/components/rect-color-and-bright-picker/brightness-icons/index.ts +8 -0
- package/src/components/rect-color-and-bright-picker/index.tsx +5 -0
- package/src/components/rect-color-and-bright-picker/res/index.ts +3 -0
- 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 +73 -0
- package/src/composeLayout.tsx +3 -1
- package/src/i18n/strings.ts +196 -0
- package/src/models/TuyaApi.ts +132 -0
- package/src/models/modules/NativePropsSlice.tsx +13 -2
- package/src/utils/interface.ts +20 -0
- package/translateKey.txt +7 -0
package/localazy.json
CHANGED
|
@@ -1191,7 +1191,14 @@
|
|
|
1191
1191
|
"MATCH:camera_calibration_desc",
|
|
1192
1192
|
"MATCH:switchstate1selection",
|
|
1193
1193
|
"MATCH:switchstate2selection",
|
|
1194
|
-
"MATCH:switchstate3selection"
|
|
1194
|
+
"MATCH:switchstate3selection",
|
|
1195
|
+
"MATCH:soilsensor_R",
|
|
1196
|
+
"MATCH:soilsensor_R1",
|
|
1197
|
+
"MATCH:soilsensor_R2",
|
|
1198
|
+
"MATCH:body_create_your_own_routine",
|
|
1199
|
+
"MATCH:setting_cur_passwd",
|
|
1200
|
+
"MATCH:setting_set_passwd",
|
|
1201
|
+
"MATCH:camera_user"
|
|
1195
1202
|
],
|
|
1196
1203
|
"replacements": {
|
|
1197
1204
|
"REGEX:% %1\\$s.*?\\)%": "{0}",
|
package/package.json
CHANGED
package/src/api/native.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {NativeModules, Platform} from 'react-native'
|
|
2
2
|
import {NativeResult, Result} from '../models/modules/Result'
|
|
3
3
|
import {DpSchema, TYSdk} from 'tuya-panel-kit'
|
|
4
|
+
import {RoutineParam} from "../utils/interface";
|
|
4
5
|
interface LDVDevicePanelManager {
|
|
5
6
|
back: () => void
|
|
6
7
|
control: (params: any, callback: (result: any) => void) => void
|
|
@@ -9,7 +10,7 @@ interface LDVDevicePanelManager {
|
|
|
9
10
|
deleteDevice: (deviceId: string, isReset: boolean, callback: (result: any) => void) => void
|
|
10
11
|
rename: (deviceId: string, name: string, callback: (result: any) => void) => void
|
|
11
12
|
toDeviceSettingsPage: (deviceId: string, isGroup: boolean) => void
|
|
12
|
-
toRoutinesPage: (params: {backTitle:string, deviceId:string}) => void
|
|
13
|
+
toRoutinesPage: (params: {backTitle:string, deviceId:string, routineParam: string}) => void
|
|
13
14
|
putJson: (deviceId: string, featureType: string, json: string, callback: (res: NativeResult<any>) => void) => void
|
|
14
15
|
getJson: (deviceId: string, featureType: string, callback: (res: NativeResult<string>) => void) => void
|
|
15
16
|
getInitiativeQueryDpsInfoWithDpsArray: (dpIds: string, deviceId: string, callback: (res: NativeResult<string>) => void) => void
|
|
@@ -215,7 +216,7 @@ function toDeviceSettingsPage(tuyaDeviceId: string, isGroup: boolean = false) {
|
|
|
215
216
|
devicePanel.toDeviceSettingsPage(tuyaDeviceId, isGroup)
|
|
216
217
|
}
|
|
217
218
|
|
|
218
|
-
function toRoutinesPage(params: {backTitle:string, deviceId:string,
|
|
219
|
+
function toRoutinesPage(params: {backTitle:string, deviceId:string, routineParam: string}) {
|
|
219
220
|
devicePanel.toRoutinesPage(params)
|
|
220
221
|
}
|
|
221
222
|
|
|
@@ -300,8 +301,8 @@ export class NativeApi {
|
|
|
300
301
|
toDeviceSettingsPage(deviceId, isGroup)
|
|
301
302
|
}
|
|
302
303
|
|
|
303
|
-
static toRoutinesPage(params: {backTitle:string, deviceId:string,
|
|
304
|
-
toRoutinesPage(params)
|
|
304
|
+
static toRoutinesPage(params: {backTitle:string, deviceId:string, routineParam?: RoutineParam}): void{
|
|
305
|
+
toRoutinesPage({...params, routineParam: JSON.stringify(params.routineParam || { pageType: 'List' })})
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
static putJson(deviceId: string, featureType: string, json: string): Promise<Result<any>> {
|
|
@@ -415,13 +416,13 @@ export const getSystemTimeFormat = async (): Promise<number> => {
|
|
|
415
416
|
|
|
416
417
|
export const getMicrophoneAccess: () => Promise<boolean> = () => {
|
|
417
418
|
return new Promise((resolve, _reject) => {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
419
|
+
devicePanel.getMicrophoneAccess(res => {
|
|
420
|
+
const haveAuthority = (typeof res?.data === 'string') ? !!res?.data && JSON.parse(res?.data)?.haveAuthority : res?.data?.haveAuthority
|
|
421
|
+
if(!res.result || (res.result && haveAuthority !== 'granted')){
|
|
422
|
+
resolve(false)
|
|
423
|
+
}
|
|
424
|
+
resolve(true)
|
|
425
|
+
})
|
|
425
426
|
})
|
|
426
427
|
}
|
|
427
428
|
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import {View} from 'react-native'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, {useCallback} 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)
|
|
9
18
|
|
|
10
19
|
export interface ColorAdjustViewProps {
|
|
11
20
|
h: number
|
|
@@ -19,7 +28,59 @@ export interface ColorAdjustViewProps {
|
|
|
19
28
|
onHSVChangeComplete: (h: number, s: number, v: number) => void
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
const
|
|
31
|
+
const NewColorPicker = React.memo((props: ColorAdjustViewProps) => {
|
|
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) => {
|
|
23
84
|
return (
|
|
24
85
|
<View>
|
|
25
86
|
<LdvColorSlider
|
|
@@ -42,14 +103,14 @@ const ColorAdjustView = (props: ColorAdjustViewProps) => {
|
|
|
42
103
|
}
|
|
43
104
|
}}/>
|
|
44
105
|
{!props.hideSat && <LdvSaturation
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
106
|
+
value={props.s}
|
|
107
|
+
minSaturation={props.minSaturation}
|
|
108
|
+
onValueChange={s => {
|
|
109
|
+
props.onHSVChange && props.onHSVChange(props.h, s, props.v)
|
|
110
|
+
}}
|
|
111
|
+
onSlidingComplete={s => {
|
|
112
|
+
props.onHSVChangeComplete(props.h, s, props.v)
|
|
113
|
+
}}/>}
|
|
53
114
|
<LdvColorBrightness
|
|
54
115
|
minBrightness={props.minBrightness}
|
|
55
116
|
value={props.v}
|
|
@@ -61,6 +122,11 @@ const ColorAdjustView = (props: ColorAdjustViewProps) => {
|
|
|
61
122
|
}}/>
|
|
62
123
|
</View>
|
|
63
124
|
)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
const ColorAdjustView = (props: ColorAdjustViewProps) => {
|
|
128
|
+
const newPalette = useNewPalette()
|
|
129
|
+
return newPalette ? <NewColorPicker {...props} /> : <OldColorPicker {...props} />
|
|
64
130
|
}
|
|
65
131
|
|
|
66
|
-
export default ColorAdjustView
|
|
132
|
+
export default ColorAdjustView
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {View} from 'react-native'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, {useCallback} from 'react'
|
|
3
3
|
import LdvColorSlider from './ldvColorSlider'
|
|
4
4
|
import Spacer from './Spacer'
|
|
5
5
|
import LdvPresetView from './ldvPresetView'
|
|
@@ -7,13 +7,17 @@ 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
|
|
10
|
+
import RectColorAndBrightPicker from "./rect-color-and-bright-picker";
|
|
11
|
+
import {useReactive, useUpdateEffect} from 'ahooks'
|
|
12
|
+
import { useNewPalette } from 'models/modules/NativePropsSlice'
|
|
11
13
|
|
|
12
14
|
const {convertX: cx} = Utils.RatioUtils
|
|
13
|
-
|
|
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);
|
|
14
19
|
|
|
15
20
|
export interface ColorTempAdjustViewProps {
|
|
16
|
-
theme?: ThemeType
|
|
17
21
|
colorTemp: number
|
|
18
22
|
brightness: number
|
|
19
23
|
minBrightness?: number
|
|
@@ -25,7 +29,87 @@ export interface ColorTempAdjustViewProps {
|
|
|
25
29
|
onBrightnessChangeComplete: (brightness: number) => void
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
const
|
|
32
|
+
const NewColorTempPicker = React.memo((props: ColorTempAdjustViewProps) => {
|
|
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
|
+
// 外部props更新时同步内部状态
|
|
51
|
+
|
|
52
|
+
state.temperature = scaleUp(colorTemp)
|
|
53
|
+
state.brightness = scaleUp(brightness)
|
|
54
|
+
}
|
|
55
|
+
}, [colorTemp, brightness])
|
|
56
|
+
|
|
57
|
+
const handleMove = useCallback((v) => {
|
|
58
|
+
onCCTChange?.(scaleDown(v.temperature))
|
|
59
|
+
onBrightnessChange?.(scaleDown(v.brightness))
|
|
60
|
+
}, [onCCTChange, onBrightnessChange])
|
|
61
|
+
|
|
62
|
+
const handleComplete = useCallback((v) => {
|
|
63
|
+
onCCTChangeComplete?.(scaleDown(v.temperature))
|
|
64
|
+
onBrightnessChangeComplete?.(scaleDown(v.brightness))
|
|
65
|
+
state.moving = false
|
|
66
|
+
}, [onCCTChangeComplete, onBrightnessChangeComplete])
|
|
67
|
+
|
|
68
|
+
const handleBrightnessMove = useCallback((v) => {
|
|
69
|
+
onBrightnessChange?.(scaleDown(v))
|
|
70
|
+
}, [onBrightnessChange])
|
|
71
|
+
|
|
72
|
+
const handleBrightnessComplete = useCallback((v) => {
|
|
73
|
+
onBrightnessChangeComplete?.(scaleDown(v))
|
|
74
|
+
state.moving = false
|
|
75
|
+
}, [onBrightnessChangeComplete])
|
|
76
|
+
|
|
77
|
+
const { temperature, brightness: stateBrightness } = state
|
|
78
|
+
const white = { temperature, brightness: stateBrightness }
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<View style={{justifyContent: 'center', alignItems: 'center'}}>
|
|
82
|
+
<View style={{
|
|
83
|
+
width: width,
|
|
84
|
+
height: cx(isSupportTemperature? 200 : 45),
|
|
85
|
+
borderRadius: cx(10),
|
|
86
|
+
borderColor: '#eeeeef',
|
|
87
|
+
borderWidth: 1,
|
|
88
|
+
overflow: 'hidden'
|
|
89
|
+
}}>
|
|
90
|
+
{
|
|
91
|
+
isSupportTemperature ? <RectColorAndBrightPicker.WhitePicker
|
|
92
|
+
value={white}
|
|
93
|
+
onGrant={() => state.moving = true}
|
|
94
|
+
onMove={handleMove}
|
|
95
|
+
onRelease={handleComplete}
|
|
96
|
+
onPress={handleComplete}
|
|
97
|
+
/> : <RectColorAndBrightPicker.BrightnessSlider
|
|
98
|
+
value={stateBrightness}
|
|
99
|
+
clickEnabled={true}
|
|
100
|
+
onGrant={() => state.moving = true}
|
|
101
|
+
onMove={handleBrightnessMove}
|
|
102
|
+
onRelease={handleBrightnessComplete}
|
|
103
|
+
onPress={handleBrightnessComplete}
|
|
104
|
+
/>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
</View>
|
|
108
|
+
</View>
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const OldColorTempPicker = React.memo((props: ColorTempAdjustViewProps) => {
|
|
29
113
|
return (
|
|
30
114
|
<View>
|
|
31
115
|
{props.isSupportTemperature &&
|
|
@@ -56,6 +140,11 @@ const ColorTempAdjustView = (props: ColorTempAdjustViewProps) => {
|
|
|
56
140
|
onSlidingComplete={props.onBrightnessChangeComplete}/>}
|
|
57
141
|
</View>
|
|
58
142
|
)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const ColorTempAdjustView = (props: ColorTempAdjustViewProps) => {
|
|
146
|
+
const newPalette = useNewPalette()
|
|
147
|
+
return newPalette ? <NewColorTempPicker {...props} /> : <OldColorTempPicker {...props} />
|
|
59
148
|
}
|
|
60
149
|
|
|
61
|
-
export default
|
|
150
|
+
export default ColorTempAdjustView
|
|
@@ -0,0 +1,269 @@
|
|
|
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
|
+
componentDidUpdate(prevProps: ColourProps) {
|
|
120
|
+
if (!_.isEqual(prevProps.value, this.props.value)) {
|
|
121
|
+
this.setState({ ...this.props.value });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
componentWillUnmount() {
|
|
126
|
+
// 清理组件状态
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
shouldComponentUpdate(nextProps: ColourProps, nextState: IState) {
|
|
130
|
+
return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
onBrightGrant = () => {
|
|
134
|
+
const { hue, saturation, value } = this.state;
|
|
135
|
+
this.firPropsEvent(this.props.onGrant, { hue, saturation, value }, { isChangeBright: true });
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
onBrightMove = (value: number) => {
|
|
139
|
+
const { hue, saturation } = this.state;
|
|
140
|
+
this.firPropsEvent(this.props.onMove, { hue, saturation, value }, { isChangeBright: true });
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
onBrightRelease = (value: number) => {
|
|
144
|
+
const { hue, saturation } = this.state;
|
|
145
|
+
this.setState({ value });
|
|
146
|
+
this.firPropsEvent(this.props.onRelease, { hue, saturation, value }, { isChangeBright: true });
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
onBrightPress = (value: number) => {
|
|
150
|
+
const { hue, saturation } = this.state;
|
|
151
|
+
this.setState({ value });
|
|
152
|
+
this.firPropsEvent(this.props.onPress, { hue, saturation, value }, { isChangeBright: true });
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
coorToValue = ({ x, y }: Point, validBound: ValidBound) => {
|
|
156
|
+
const { hueOffset } = this.props;
|
|
157
|
+
const { width, height, x: validStartX, y: validStartY } = validBound;
|
|
158
|
+
const { value } = this.state;
|
|
159
|
+
let hue = Math.round(((x - validStartX) / width) * 360 + hueOffset) % 360;
|
|
160
|
+
const saturation = Math.round(((y - validStartY) / height) * 1000);
|
|
161
|
+
|
|
162
|
+
// hueOffset 不等于0时,最左边与最右边的值一样,为确保不会滑到最左边时跳到最右边
|
|
163
|
+
// 滑到最左边时,hue + 1;
|
|
164
|
+
if (hueOffset !== 0) {
|
|
165
|
+
if (Math.abs(x - validStartX) < 1) {
|
|
166
|
+
hue += 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { hue, saturation, value };
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
valueToCoor = (hsv: IHsv, _origin: Point, validBound: ValidBound): Point => {
|
|
174
|
+
const { hueOffset } = this.props;
|
|
175
|
+
const { width, height, x: validStartX, y: validStartY } = validBound;
|
|
176
|
+
const { hue, saturation } = hsv;
|
|
177
|
+
let x = ((hue - hueOffset) / 360) * width;
|
|
178
|
+
if (x <= 0) {
|
|
179
|
+
x = width + x;
|
|
180
|
+
}
|
|
181
|
+
const y = (saturation / 1000) * height;
|
|
182
|
+
|
|
183
|
+
return { x: x + validStartX, y: y + validStartY };
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
valueToColor = (hsv: IHsv): string => {
|
|
187
|
+
const { hue, saturation, value } = hsv;
|
|
188
|
+
return ColorUtils.hsv2rgba(hue!, saturation, value) || 'transparent';
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
firPropsEvent(cb: (params?: any) => void, ...args: any[]) {
|
|
192
|
+
typeof cb === 'function' && cb(...args);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
handlePickerGrant = () => {
|
|
196
|
+
const { hue, saturation, value } = this.state;
|
|
197
|
+
this.firPropsEvent(this.props.onGrant, { hue, saturation, value });
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
handlePickerMove = (hsv: IHsv) => {
|
|
201
|
+
this.firPropsEvent(this.props.onMove, hsv);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
handlePickerRelease = (hsv: IHsv) => {
|
|
205
|
+
this.setState({ ...hsv });
|
|
206
|
+
this.firPropsEvent(this.props.onRelease, hsv);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
handlePickerPress = (hsv: IHsv) => {
|
|
210
|
+
this.setState({ ...hsv });
|
|
211
|
+
this.firPropsEvent(this.props.onPress, hsv);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
initData = async () => {};
|
|
215
|
+
render() {
|
|
216
|
+
const {
|
|
217
|
+
style,
|
|
218
|
+
rectStyle,
|
|
219
|
+
brightOption,
|
|
220
|
+
lossShow,
|
|
221
|
+
lossSliderColor,
|
|
222
|
+
clickEnabled,
|
|
223
|
+
hideBright,
|
|
224
|
+
opacityAnimationValue,
|
|
225
|
+
opacityAnimationDuration,
|
|
226
|
+
...pickerProps
|
|
227
|
+
} = this.props;
|
|
228
|
+
const { hue, saturation, value: bright } = this.state;
|
|
229
|
+
const sliderProps: any = {};
|
|
230
|
+
if (lossShow) {
|
|
231
|
+
sliderProps.activeColor = lossSliderColor;
|
|
232
|
+
}
|
|
233
|
+
return (
|
|
234
|
+
<View style={[{ flex: 1 }, style]}>
|
|
235
|
+
<RectPicker
|
|
236
|
+
coorToValue={this.coorToValue}
|
|
237
|
+
valueToColor={this.valueToColor}
|
|
238
|
+
valueToCoor={this.valueToCoor}
|
|
239
|
+
value={{ hue, saturation, value: bright }}
|
|
240
|
+
lossShow={lossShow}
|
|
241
|
+
clickEnabled={clickEnabled}
|
|
242
|
+
opacityAnimationValue={opacityAnimationValue}
|
|
243
|
+
opacityAnimationDuration={opacityAnimationDuration}
|
|
244
|
+
{...pickerProps}
|
|
245
|
+
style={rectStyle}
|
|
246
|
+
onGrant={this.handlePickerGrant}
|
|
247
|
+
onMove={this.handlePickerMove}
|
|
248
|
+
onRelease={this.handlePickerRelease}
|
|
249
|
+
onPress={this.handlePickerPress}
|
|
250
|
+
initData={this.initData}
|
|
251
|
+
/>
|
|
252
|
+
{!hideBright && (
|
|
253
|
+
<Slider
|
|
254
|
+
opacityAnimationValue={opacityAnimationValue}
|
|
255
|
+
opacityAnimationDuration={opacityAnimationDuration}
|
|
256
|
+
{...brightOption}
|
|
257
|
+
{...sliderProps}
|
|
258
|
+
value={bright}
|
|
259
|
+
clickEnabled={clickEnabled}
|
|
260
|
+
onGrant={this.onBrightGrant}
|
|
261
|
+
onMove={this.onBrightMove}
|
|
262
|
+
onRelease={this.onBrightRelease}
|
|
263
|
+
onPress={this.onBrightPress}
|
|
264
|
+
/>
|
|
265
|
+
)}
|
|
266
|
+
</View>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
}
|