Commit 5233fb98 authored by zhushengjie's avatar zhushengjie

彩环修改

parent 82d6e4a9
......@@ -10,5 +10,5 @@
"DeviceKit": "2.4.7"
},
"baseversion": "2.9.5",
"productId": "qton0thk3uxf77hv"
"productId": "hewd8dsaiwxpznpr"
}
......@@ -17,8 +17,19 @@ export interface DpState {
do_not_disturb: boolean;
}
export interface ColorData {
// mouseMoveX: number;
// mouseMoveY: number;
// locationX: number;
// locationY: number;
ifDrag: boolean;
}
type UpdateDpStatePayload = Partial<DpState>;
type UpdateColorDataPayload = Partial<ColorData>;
/**
* 定义一个 dpStateAtom
*
......@@ -34,6 +45,10 @@ export const dpStateAtom = atom<DpState, UpdateDpStatePayload>(null, (get, set,
set(dpStateAtom, { ...(get(dpStateAtom) || {}), ...payload });
});
export const colorDataAtom = atom<ColorData, UpdateColorDataPayload>(null, (get, set, payload) => {
set(colorDataAtom, { ...(get(colorDataAtom) || {}), ...payload });
});
/**
* 定义一个基于 dpStateAtom 的选择器
*
......@@ -47,3 +62,9 @@ export const dpStateAtom = atom<DpState, UpdateDpStatePayload>(null, (get, set,
* @docs 详见 https://jotai.org/docs/utils/select-atom
*/
export const selectDpStateAtom = selectAtom<DpState, DpState>(dpStateAtom, data => data, deepEqual);
export const selectColorDataAtom = selectAtom<ColorData, ColorData>(
colorDataAtom,
data => data,
deepEqual
);
......@@ -6,15 +6,17 @@
.header {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
// display: flex;
// justify-content: center;
// align-items: center;
.circleContent {
position: relative;
z-index: 30;
left: 100px;
top: 50px;
background-image: url(./tempBg.png);
border:none;
border: none;
.circle {
position: absolute;
......@@ -22,12 +24,12 @@
left: 0;
top: 0;
border-radius: 50%;
border: 10rpx solid #ffffff;
border: 10px solid #ffffff;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: 40rpx;
font-size: 20px;
-webkit-user-select: none;
}
......
......@@ -14,7 +14,7 @@ const HubCircle: React.FC<Props> = props => {
const { hsv2rgb, rgb2hex } = utils;
// document.getElementById;
const dataSourse = {
num: 0,
isDrag: false,
angleLimit: 135, // 角度限制
angleValue: 0, // 角度信息 0 ~ 360
......@@ -23,29 +23,29 @@ const HubCircle: React.FC<Props> = props => {
containerWidth: 400,
containerStyle: {
width: '400rpx',
height: '400rpx',
backgroundSize: '400rpx 400rpx',
width: '200px',
height: '200px',
backgroundSize: '200px 200px',
},
circleStyle: {
width: '200rpx',
height: '200rpx',
left: '100rpx',
top: '100rpx',
width: '100px',
height: '100px',
left: '50px',
top: '50px',
},
containerOffset: {
// 容器位置
x: 100,
y: 100,
y: 150,
},
mouse_offset: { x: 0, y: 0 },
circle_r: 200, // 圆形外半径(容器宽度/2)
circle_b: 84, // 圆形边距
bar_r: 42, // 小球半径(圆形边距/2)
circle_r: 100, // 圆形外半径(容器宽度/2)
circle_b: 42, // 圆形边距
bar_r: 21, // 小球半径(圆形边距/2)
};
const [addFlag, setAddFlag] = useState(true);
......@@ -56,8 +56,6 @@ const HubCircle: React.FC<Props> = props => {
{ temp_value: 300, bright_value: 300, color: '#FFE2A4', active: false },
]);
const [isDrag, setIsDrag] = useState(false);
const [dataState, setDataState] = useState({
angleValue: 0, // 角度值 0 ~ 360
angleShow: 0, // 角度展示 0 ~ 180
......@@ -67,7 +65,7 @@ const HubCircle: React.FC<Props> = props => {
const [circleLocation, setCircleLocation] = useState({
// 小球位置
left: 158,
left: 79,
top: 0,
});
......@@ -85,15 +83,6 @@ const HubCircle: React.FC<Props> = props => {
const handleCirleClick = (e: any, item: colorItem): void => {
e.origin.stopPropagation();
if (dataSourse.num === 0) {
// 获取容器位置 (无法操作DOM,暂时通过初次计算获取)
dataSourse.num = 1;
const X = e.touches[0].pageX + dataSourse.bar_r - dataSourse.containerWidth / 2;
const Y = e.touches[0].pageY;
dataSourse.containerOffset.x = X;
dataSourse.containerOffset.y = Y;
}
const index = colorArr.findIndex(el => {
return item.bright_value === el.bright_value && el.temp_value === item.temp_value;
});
......@@ -132,8 +121,6 @@ const HubCircle: React.FC<Props> = props => {
const color = hsv2rgb(h, s, v);
const nowColor = rgb2hex(color[0], color[1], color[2]);
console.log(nowColor);
setDataState({
...dataState,
nowColor,
......@@ -165,12 +152,13 @@ const HubCircle: React.FC<Props> = props => {
const mouse_offset_x =
e.origin.touches[0].clientX -
dataSourse.containerOffset.x -
e.origin.currentTarget.offsetLeft -
e.origin.target.offsetLeft -
dataSourse.bar_r;
const mouse_offset_y = -(
e.origin.touches[0].clientY -
dataSourse.containerOffset.y -
e.origin.currentTarget.offsetTop -
e.origin.target.offsetTop -
dataSourse.bar_r
);
dataSourse.mouse_offset.x = mouse_offset_x;
......@@ -200,7 +188,7 @@ const HubCircle: React.FC<Props> = props => {
updateContent(radian);
if (!isDrag) {
if (!dataSourse.isDrag) {
return;
}
setCircleLocation({
......@@ -223,9 +211,18 @@ const HubCircle: React.FC<Props> = props => {
// 0 ~ 180
const angleShow = angleValue > 180 ? 360 - angleValue : angleValue;
const { angleLimit } = dataSourse;
if (angleShow > angleLimit) {
dataSourse.isDrag = false;
return;
}
if (!dataSourse.isDrag) {
dataSourse.isDrag = true;
}
const tempStart = dataSourse.tempValue[0];
const tempEnd = dataSourse.tempValue[1];
const { angleLimit } = dataSourse;
let tempshow = (tempEnd - tempStart) / 2 + tempStart; // 中间值 角度对应0
if (angleValue < 180) {
......@@ -236,14 +233,6 @@ const HubCircle: React.FC<Props> = props => {
tempshow -= ((tempEnd - tempshow) / angleLimit) * angleShow;
}
if (angleShow > angleLimit) {
setIsDrag(false);
return;
}
if (!isDrag) {
setIsDrag(true);
}
tempshow = Math.floor(tempshow);
setDataState({
......@@ -264,10 +253,10 @@ const HubCircle: React.FC<Props> = props => {
<View
className={styles.circleBar}
style={{
left: `${circleLocation.left}rpx`,
top: `${circleLocation.top}rpx`,
width: `${dataSourse.bar_r * 2}rpx`,
height: `${dataSourse.bar_r * 2}rpx`,
left: `${circleLocation.left}px`,
top: `${circleLocation.top}px`,
width: `${dataSourse.bar_r * 2}px`,
height: `${dataSourse.bar_r * 2}px`,
}}
onTouchStart={handleBarTouch}
onTouchMove={handleBarMove}
......
import React, { useState, useCallback } from 'react';
import { utils } from '@ray-js/panel-sdk';
import { useAtomValue, useSetAtom } from 'jotai';
import { ColorData, colorDataAtom, selectColorDataAtom } from '@/atoms';
import { View, Text, Slider, Image, usePageEvent } from '@ray-js/ray';
import styles from './index.module.less';
import { Props } from './index.type';
import imgs from '../../res';
const { hsv2rgbString } = utils;
// 平移法
const HubColorCircle: React.FC<Props> = props => {
const dpState = props.DpStateData;
const codeMap = props.DpCodesMap;
const setColorStateAtom = useSetAtom(colorDataAtom);
const colorStateInAtom = useAtomValue(selectColorDataAtom);
const data = {
radius: 135, // 容器半径
innerRadius: 76, // 内半径
thumbRadius: 27.5, // 圆球半径
thumbInnerRadius: 22.5, // 圆球内环
ringSize: 135 - 76, // 圆环尺寸
colorThumRadius: 76 - 5,
cx: 135 - 27.5, // 圆心相对父容器位置
cy: 135 - 27.5, // 圆心相对父容器位置
fixedLength: 135 - (135 - 76) * 0.5, // 可拖动圆球至原点的固定距离(令圆球始终在在色环中居中)
containerOffsetX: 135 - 27.5,
containerOffsetY: (135 - 76) * 0.5 - 27.5 * 0.5,
mouseMove: {
// 父元素偏移
x: 0,
y: 0,
},
location: {
// 点击时的小球位置
x: 0,
y: 0,
},
disabled: false,
RingBackground: imgs.colorBg,
hue: 90, // 色相
};
const atomState = {
// 父元素偏移
mouseMoveX: 0,
mouseMoveY: 0,
// 点击时的小球位置
locationX: 0,
locationY: 0,
};
const hueToColor = hue => {
return hsv2rgbString(hue, 1000, 1000);
};
const [translateX, setTranslateX] = useState(0);
const [translateY, setTranslateY] = useState(0);
const [nowColor, setNowColor] = useState(hueToColor(data.hue));
const [hueState, sethueState] = useState(data.hue);
const getCoordByHue = (hue: number) => {
const rad = ((360 - hue) * Math.PI) / 180;
const x = data.cx + data.fixedLength * Math.cos(rad);
const y = data.cy + data.fixedLength * Math.sin(rad);
return { x, y };
};
const handleBarTouch = e => {
atomState.locationX = e.origin.currentTarget.offsetLeft;
atomState.locationY = e.origin.currentTarget.offsetTop;
setColorStateAtom(atomState);
console.log(data.location, 'touch');
atomState.mouseMoveX = e.origin.currentTarget.offsetLeft;
atomState.mouseMoveY = e.origin.currentTarget.offsetTop;
};
const getHueByCoord = (dx: number, dy: number) => {
// 0 ~ 2π
const rad = getRadianByCoord(dx, dy);
return (rad * 180) / Math.PI;
};
const getRadianByCoord = (dx: number, dy: number) => {
const { thumbRadius } = data;
// 相对中心点的坐标
const xCenter = dx - data.cx - thumbRadius;
const yCenter = dy - data.cy - thumbRadius;
let rad = Math.atan2(yCenter, xCenter);
if (xCenter > 0 && yCenter > 0) rad = Math.PI * 2 - rad;
if (xCenter < 0 && yCenter > 0) rad = Math.PI * 2 - rad;
if (xCenter < 0 && yCenter < 0) rad = Math.abs(rad);
if (xCenter > 0 && yCenter < 0) rad = Math.abs(rad);
if (xCenter === 0 && yCenter > 0) rad = (Math.PI * 3) / 2;
if (xCenter === 0 && yCenter < 0) rad = Math.PI / 2;
return rad;
};
const handleMove = e => {
// 最近一次的移动路程,dx的正负决定了移动的正负
const { locationX, locationY } = colorStateInAtom;
const dx = e.origin.touches[0].clientX - locationX;
const dy = e.origin.touches[0].clientY - locationY;
const hue = Math.round(getHueByCoord(dx, dy));
const { x = 0, y = 0 } = getCoordByHue(hue);
const color = hueToColor(hue);
setTranslateX(x);
setTranslateY(y);
setNowColor(color);
sethueState(hue);
};
return (
<View className={styles.header}>
<View
className={styles.circleContent}
style={{ width: `${data.radius * 2}px`, height: `${data.radius * 2}px` }}
>
{/* 圆环 */}
<View
className={styles.sectionRing}
style={{ width: `${data.radius * 2}px`, height: `${data.radius * 2}px` }}
>
<Image
style={{
width: `${data.radius * 2}px`,
height: `${data.radius * 2}px`,
borderRadius: '50%',
}}
src={imgs.colorBg}
/>
</View>
{/* 圆环中间色彩值 */}
<View
className={styles.colorThum}
style={{
position: 'absolute',
left: `${data.radius - data.colorThumRadius}px`,
top: `${data.radius - data.colorThumRadius}px`,
width: `${data.colorThumRadius * 2}px`,
height: `${data.colorThumRadius * 2}px`,
borderRadius: '50%',
backgroundColor: nowColor,
}}
>
Angle:{hueState}°
</View>
{/* 圆球 */}
<View
className={styles.bar}
style={{
top: `${data.containerOffsetY}px`,
left: `${data.containerOffsetX}px`,
width: `${data.thumbRadius * 2}px`,
height: `${data.thumbRadius * 2}px`,
borderRadius: '50%',
opacity: 1,
transform: `translateX(${translateX}px) translateY(${translateY}px)`,
}}
onTouchStart={handleBarTouch}
onTouchMove={handleMove}
>
<View
style={{
width: `${data.thumbInnerRadius * 2}px`,
height: `${data.thumbInnerRadius * 2}px`,
borderRadius: '50%',
backgroundColor: nowColor,
}}
/>
</View>
</View>
</View>
);
};
export default HubColorCircle;
.sectionRing {
align-items: center;
justify-content: center;
}
.bar {
position: absolute;
align-items: center;
justify-content: center;
background-color: '#fff';
box-shadow: 0 5rpx 12rpx rgba(0, 0, 0, 0.6);
}
.sectionRing {
align-items: center;
justify-content: center;
}
.bar {
position: absolute;
align-items: center;
justify-content: center;
background-color: '#fff';
box-shadow: 0 5rpx 12rpx rgba(0, 0, 0, 0.6);
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
.header {
flex: 1;
// display: flex;
// justify-content: center;
// align-items: center;
.circleContent {
position: relative;
z-index: 30;
left: 100px;
top: 50px;
background-image: url(./colorBg.png);
border: none;
.circle {
position: absolute;
z-index: 10;
left: 0;
top: 0;
border-radius: 50%;
border: 10px solid #ffffff;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: 20px;
-webkit-user-select: none;
}
.circleBar {
position: absolute;
z-index: 50;
border-radius: 50%;
background-color: transparent;
border: 4rpx solid rgba(255, 255, 255, 1);
cursor: pointer;
box-shadow: 0 5rpx 12rpx rgba(0, 0, 0, 0.6);
}
}
}
.panel {
.configList {
margin-bottom: 50rpx;
display: flex;
justify-content: center;
align-items: center;
.cutBar {
color: red;
font-size: 24rpx;
}
.addStyle {
color: white;
font-size: 24rpx;
}
.icoImg {
width: 30rpx;
height: 30rpx;
}
.slider {
width: 500rpx;
}
.SliderValue {
color: #fff;
font-size: 16rpx;
width: 20rpx;
}
.colorCircle {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
border: 1rpx solid #fff;
}
.colorCircle:nth-child(n + 1) {
margin-left: 15rpx;
}
.cutBar {
color: red;
}
.addBar {
color: #fff;
}
}
}
.circleContent {
width: 200rpx;
height: 200rpx;
border: 1rpx solid #000;
}
.circleBar {
width: 200rpx;
height: 200rpx;
}
}
// .header {
// display: flex;
// // align-items: center;
// // justify-content: center;
// }
// .circleContent {
// position: relative;
// }
// .sectionRing {
// display: flex;
// align-items: center;
// justify-content: center;
// }
// .bar {
// display: flex;
// position: absolute;
// align-items: center;
// justify-content: center;
// background-color: '#fff';
// box-shadow: 0 5rpx 12rpx rgba(0, 0, 0, 0.6);
// }
// .colorThum {
// display: flex;
// position: absolute;
// align-items: center;
// color: white;
// font-size: 16px;
// font-weight: 700;
// }
import React, { useState, useCallback } from 'react';
import React, { useState } from 'react';
import { utils } from '@ray-js/panel-sdk';
import { getElementById } from '@ray-js/api';
import { View, Text, Slider, Image, usePageEvent } from '@ray-js/ray';
import { useAtomValue, useSetAtom } from 'jotai';
import { ColorData, colorDataAtom, selectColorDataAtom } from '@/atoms';
import { View, Text, Slider, Image } from '@ray-js/ray';
import styles from './index.module.less';
import { Props } from './index.type';
import imgs from '../../res';
const { hsv2rgbString } = utils;
type colorItem = Record<string, any>;
// onStartShouldSetPanResponder: this.handleSetResponder, 判断是否按中滑块
// onMoveShouldSetPanResponder: () => this.locked,
// onPanResponderGrant: this.handleGrant,
// onPanResponderMove: this.handleMove, 开始移动
// onPanResponderRelease: this.handleRelease, 完成一个手势操作
const HubColorCircle: React.FC<Props> = props => {
const HubCircle: React.FC<Props> = props => {
const dpState = props.DpStateData;
const codeMap = props.DpCodesMap;
const data = {
radius: 135,
innerRadius: 76, // 内半径
thumbRadius: 27.5, // 圆球半径
thumbInnerRadius: 22.5, // 圆球内环
ringSize: 135 - 76, // 圆环尺寸
cx: 135 - 27.5,
cy: 135 - 27.5,
const setColorStateAtom = useSetAtom(colorDataAtom);
const colorStateInAtom = useAtomValue(selectColorDataAtom);
const { hsv2rgb, rgb2hex, hsv2rgbString } = utils;
// document.getElementById;
const dataSourse = {
containerWidth: 400,
fixedLength: 135 - (135 - 76) * 0.5, // 可拖动圆球至原点的固定距离(令圆球始终在在色环中居中)
containerStyle: {
width: '200px',
height: '200px',
backgroundSize: '200px 200px',
},
containerOffset: {
// 容器位置
x: 0,
y: 0,
x: 100,
y: 150,
},
mouseMove: {
// 父元素偏移
x: 0,
y: 0,
},
mouse_offset: { x: 0, y: 0 },
location: {
// 点击时的小球位置
x: 0,
y: 0,
},
circle_r: 100, // 圆形外半径(容器宽度/2)
circle_b: 42, // 圆形边距
bar_r: 21, // 小球半径(圆形边距/2)
hue: 270,
};
const hueToColor = (h: number, s = 100, v = 100, a = 1) => {
return hsv2rgbString(h, s, v, a);
};
const [addFlag, setAddFlag] = useState(true);
const [colorArr, setColorArr] = useState<colorItem[]>([
{ hue: 0, temp_value: 1000, bright_value: 1000, color: hueToColor(0), active: false },
{ hue: 90, temp_value: 1000, bright_value: 1000, color: hueToColor(90), active: false },
{ hue: 180, temp_value: 1000, bright_value: 1000, color: hueToColor(180), active: false },
]);
const [dataState, setDataState] = useState({
hue: 90, // 角度展示 0 ~ 180
temp_value: 500,
bright_value: 500,
nowColor: hueToColor(90), // 当前颜色
});
const [circleLocation, setCircleLocation] = useState({
// 小球位置
left: 79,
top: 0,
});
const toParseInt = (value: number): number => {
return Math.floor(value);
};
const handleCirleClick = (e: any, item: colorItem): void => {
e.origin.stopPropagation();
const index = colorArr.findIndex(el => {
return (
item.hue === el.hue &&
item.bright_value === el.bright_value &&
el.temp_value === item.temp_value
);
});
disabled: false,
RingBackground: imgs.colorBg,
hue: 0, // 色相
if (item.active) {
colorArr.splice(index, 1);
if (colorArr.length < 6) {
setAddFlag(true);
}
} else {
for (let i = 0; i < colorArr.length; i++) {
colorArr[i].active = false;
}
colorArr[index].active = true;
}
const value = [...colorArr];
setColorArr(value);
};
const hueToColor = hue => {
return hsv2rgbString(hue, 1000, 1000);
const handleCircleAdd = () => {
if (colorArr.length > 5) {
setAddFlag(false);
return;
}
const h = dataState.hue;
const nowColor = hueToColor(h, dataState.temp_value / 10, dataState.bright_value / 9.9);
setDataState({
...dataState,
nowColor,
});
const item = {
hue: h,
temp_value: dataState.temp_value,
bright_value: dataState.bright_value,
color: nowColor,
active: false,
};
const flag = colorArr.some((el: colorItem) => {
return (
item.hue === el.hue &&
item.bright_value === el.bright_value &&
item.temp_value === el.temp_value
);
});
if (flag) {
// setAddFlag(true);
return;
}
colorArr.push(item);
const value = [...colorArr];
setColorArr(value);
};
const [translateX, setTranslateX] = useState(0);
const [translateY, setTranslateY] = useState(0);
const [nowColor, setNowColor] = useState(hueToColor(data.hue));
const handleBarTouch = (e: any) => {
e.origin.stopPropagation();
setColorStateAtom({ ifDrag: true });
// 移动距离:小球的坐标位置-容器的偏移位置-小球相对容器的偏移位置-小球半径
const mouse_offset_x =
e.origin.touches[0].clientX -
dataSourse.containerOffset.x -
e.origin.target.offsetLeft -
dataSourse.bar_r;
const getCoordByHue = (hue: number) => {
const rad = ((360 - hue) * Math.PI) / 180;
const x = data.cx + data.fixedLength * Math.cos(rad);
const y = data.cy + data.fixedLength * Math.sin(rad);
return { x, y };
const mouse_offset_y = -(
e.origin.touches[0].clientY -
dataSourse.containerOffset.y -
e.origin.target.offsetTop -
dataSourse.bar_r
);
dataSourse.mouse_offset.x = mouse_offset_x;
dataSourse.mouse_offset.y = mouse_offset_y;
};
const handleBarTouch = e => {
data.location.x = e.origin.touches[0].clientX;
data.location.y = e.origin.touches[0].clientY;
data.mouseMove.x = e.origin.currentTarget.offsetLeft;
data.mouseMove.y = e.origin.currentTarget.offsetTop;
const handleBarMove = (e: any) => {
e.origin.stopPropagation();
const event_offset_x =
e.origin.touches[0].clientX -
dataSourse.mouse_offset.x -
dataSourse.containerOffset.x -
dataSourse.circle_r;
const event_offset_y = -(
e.origin.touches[0].clientY -
dataSourse.mouse_offset.y -
dataSourse.containerOffset.y -
dataSourse.circle_r
);
const radian = Math.atan2(event_offset_y, event_offset_x);
const x = Math.cos(radian) * (dataSourse.circle_r - dataSourse.circle_b / 2);
const y = Math.sin(radian) * (dataSourse.circle_r - dataSourse.circle_b / 2);
const left = x - dataSourse.bar_r + dataSourse.circle_r;
const top = dataSourse.circle_r - (y + dataSourse.bar_r);
if (!colorStateInAtom.ifDrag) {
return;
}
updateContent(radian);
setCircleLocation({
...circleLocation,
left,
top,
});
};
const getHueByCoord = (dx: number, dy: number) => {
// 0 ~ 2π
const rad = getRadianByCoord(dx, dy);
return (rad * 180) / Math.PI;
const updateContent = (radian: number) => {
let angle = radian * (180 / Math.PI); // -180 ~ 180
if (angle >= -180 && angle <= 90) {
angle = 90 - angle;
} else {
angle = 360 - (angle - 90);
}
// 0 ~ 360
// 转为逆时针顺序
let hue = Math.floor(360 - angle + 90);
if (hue >= 360) {
hue -= 360;
}
const nowColor = hueToColor(hue, dataState.temp_value / 10, dataState.bright_value / 9.9);
setDataState({
...dataState,
hue,
nowColor,
});
};
const getRadianByCoord = (dx: number, dy: number) => {
const { thumbRadius } = data;
const xCenter = dx - data.cx - thumbRadius;
const yCenter = dy - data.cy - thumbRadius;
let rad = Math.atan2(yCenter, xCenter);
if (xCenter > 0 && yCenter > 0) rad = Math.PI * 2 - rad;
if (xCenter < 0 && yCenter > 0) rad = Math.PI * 2 - rad;
if (xCenter < 0 && yCenter < 0) rad = Math.abs(rad);
if (xCenter > 0 && yCenter < 0) rad = Math.abs(rad);
if (xCenter === 0 && yCenter > 0) rad = (Math.PI * 3) / 2;
if (xCenter === 0 && yCenter < 0) rad = Math.PI / 2;
return rad;
const handleStateChange = (type, e) => {
if (type === 'temp_value') {
const temp_value = e.value;
const nowColor = hueToColor(dataState.hue, temp_value / 10, dataState.bright_value / 9.9);
setDataState({
...dataState,
temp_value,
nowColor,
});
}
if (type === 'bright_value') {
const bright_value = e.value;
const nowColor = hueToColor(dataState.hue, dataState.temp_value / 10, bright_value / 9.9);
setDataState({
...dataState,
bright_value,
nowColor,
});
}
};
const handleMove = e => {
// 最近一次的移动路程
const dx = e.origin.touches[0].clientX - data.location.x;
const dy = e.origin.touches[0].clientY - data.location.y;
const hue = Math.round(getHueByCoord(dx, dy));
const { x = 0, y = 0 } = getCoordByHue(hue);
const color = hueToColor(hue);
setTranslateX(x);
setTranslateY(y);
setNowColor(color);
const handleBarEnd = () => {
setColorStateAtom({ ifDrag: false });
};
return (
<View className={styles.box} style={{ width: data.radius * 2, height: data.radius * 2 }}>
{/* 圆环 */}
<View
className={styles.sectionRing}
style={{ width: data.radius * 2, height: data.radius * 2 }}
>
<Image
style={{
width: data.radius * 2,
height: data.radius * 2,
borderRadius: data.radius,
}}
src={imgs.colorBg}
/>
<View className={styles.box}>
<View className={styles.header}>
<View className={styles.circleContent} id="circleContent" style={dataSourse.containerStyle}>
<View
className={styles.circle}
style={{
width: '100px',
height: '100px',
left: '50px',
top: '50px',
backgroundColor: dataState.nowColor,
}}
>
{dataState.hue}°
</View>
<View
className={styles.circleBar}
style={{
left: `${circleLocation.left}px`,
top: `${circleLocation.top}px`,
width: `${dataSourse.bar_r * 2}px`,
height: `${dataSourse.bar_r * 2}px`,
}}
onTouchStart={handleBarTouch}
onTouchMove={handleBarMove}
onTouchEnd={handleBarEnd}
/>
</View>
</View>
{/* 圆球 */}
<View
className={styles.bar}
style={{
width: data.thumbRadius * 2,
height: data.thumbRadius * 2,
borderRadius: data.thumbRadius,
opacity: 1,
transform: `translateX(${translateX}) translateY(${translateY})`,
}}
onTouchStart={handleBarTouch}
onTouchMove={handleMove}
>
<View
style={{
width: data.thumbInnerRadius * 2,
height: data.thumbInnerRadius * 2,
borderRadius: data.thumbInnerRadius,
backgroundColor: nowColor,
}}
/>
<View className={styles.panel}>
<View className={styles.configList}>
<Image src={imgs.icon_bhd} className={styles.icoImg} />
<View className={styles.slider}>
<Slider
activeColor="#fff"
backgroundColor="#333333"
min={0}
max={1000}
step={1}
value={dataState.temp_value}
onChange={e => handleStateChange('temp_value', e)}
/>
</View>
<Text className={styles.SliderValue}>
{toParseInt((dataState.temp_value / 1000) * 100)}%
</Text>
</View>
<View className={styles.configList}>
<Image src={imgs.icon_ld} className={styles.icoImg} />
<View className={styles.slider}>
<Slider
activeColor="#fff"
backgroundColor="#333333"
min={10}
max={1000}
step={1}
value={dataState.bright_value}
onChange={e => handleStateChange('bright_value', e)}
/>
</View>
<Text className={styles.SliderValue}>
{toParseInt((dataState.bright_value / 990) * 100)}%
</Text>
</View>
<View className={styles.configList}>
{colorArr.map(item => (
<View
className={styles.colorCircle}
style={{ backgroundColor: item.color, borderColor: item.active ? 'red' : 'white' }}
key={item.color}
onClick={e => handleCirleClick(e, item)}
>
{item.active && <View className={styles.cutBar}>-</View>}
</View>
))}
{addFlag && (
<View className={`${styles.colorCircle} ${styles.addBar}`} onClick={handleCircleAdd}>
<View className={styles.addStyle}>+</View>
</View>
)}
</View>
</View>
</View>
);
};
export default HubColorCircle;
// nativeEvent
// changedTouches - 在上一次事件之后,所有发生变化的触摸事件的数组集合(即上一次事件后,所有移动过的触摸点)
// identifier - 触摸点的 ID
// locationX - 触摸点相对于父元素的横坐标
// locationY - 触摸点相对于父元素的纵坐标
// pageX - 触摸点相对于根元素的横坐标
// pageY - 触摸点相对于根元素的纵坐标
// target - 触摸点所在的元素 ID
// timestamp - 触摸事件的时间戳,可用于移动速度的计算
// touches - 当前屏幕上的所有触摸点的集合
// 一个gestureState对象有如下的字段:
// stateID - 触摸状态的 ID。在屏幕上有至少一个触摸点的情况下,这个 ID 会一直有效。
// moveX - 最近一次移动时的屏幕横坐标
// moveY - 最近一次移动时的屏幕纵坐标
// x0 - 当响应器产生时的屏幕坐标
// y0 - 当响应器产生时的屏幕坐标
// dx - 从触摸操作开始时的累计横向路程
// dy - 从触摸操作开始时的累计纵向路程
// vx - 当前的横向移动速度
// vy - 当前的纵向移动速度
// numberActiveTouches - 当前在屏幕上的有效触摸点的数量
export default HubCircle;
@subtractHeight: 200rpx;
@subtractHeight: 100px;
.home {
height: 100vh;
......@@ -38,17 +38,17 @@
}
.switch {
width: 120rpx;
height: 120rpx;
width: 60px;
height: 60px;
background: #43aaff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
position: absolute;
border: 4rpx solid rgba(0, 0, 0, 0.8);
border: 4px solid rgba(0, 0, 0, 0.8);
z-index: 500;
left: calc(50% - 60rpx);
left: calc(50% - 40px);
bottom: 100rpx;
}
......@@ -57,6 +57,6 @@
}
.CombinedShape {
width: 60rpx;
height: 60rpx;
width:40px;
height: 40px;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment