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;
// }
This diff is collapsed.
@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