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 styles from './index.module.less'; import { Props } from './index.type'; import imgs from '../../res'; type colorItem = Record; const HubCircle: React.FC = props => { const dpState = props.DpStateData; const codeMap = props.DpCodesMap; const { hsv2rgb, rgb2hex } = utils; // document.getElementById; const dataSourse = { num: 0, angleLimit: 135, // 角度限制 angleValue: 0, // 角度信息 0 ~ 360 tempValue: [2700, 6500], // 色温范围 containerWidth: 400, containerStyle: { width: '400rpx', height: '400rpx', backgroundSize: '400rpx 400rpx', }, circleStyle: { width: '200rpx', height: '200rpx', left: '100rpx', top: '100rpx', }, containerOffset: { // 容器位置 x: 100, y: 100, }, mouse_offset: { x: 0, y: 0 }, circle_r: 200, // 圆形外半径(容器宽度/2) circle_b: 84, // 圆形边距 bar_r: 42, // 小球半径(圆形边距/2) }; const [addFlag, setAddFlag] = useState(true); const [colorArr, setColorArr] = useState([ { temp_value: 100, bright_value: 100, color: '#CEEDFE', active: false }, { temp_value: 200, bright_value: 200, color: '#F5FCFF', active: false }, { 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 tempshow: (6500 - 2700) / 2 + 2700, // 色温展示 nowColor: '#FFE2A4', // 当前颜色 }); const [circleLocation, setCircleLocation] = useState({ // 小球位置 left: 158, top: 0, }); usePageEvent('onShow', () => { console.log('=== home onShow'); getElementById('circleContent').then(res => { console.log(res, 'res'); }); }); const toParseInt = (value: number): number => { return Math.floor(value); }; 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; }); 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 handleCircleAdd = () => { if (colorArr.length > 5) { setAddFlag(false); return; } const h = 0; const s = toParseInt( (dpState.bright_value / (codeMap.bright_value.property.max - codeMap.bright_value.property.min)) * 100 ); const v = toParseInt( (dpState.bright_value / (codeMap.bright_value.property.max - codeMap.bright_value.property.min)) * 100 ); const color = hsv2rgb(h, s, v); const nowColor = rgb2hex(color[0], color[1], color[2]); console.log(nowColor); setDataState({ ...dataState, nowColor, }); const item = { temp_value: dpState.temp_value, bright_value: dpState.bright_value, color: nowColor, active: false, }; const flag = colorArr.some((el: colorItem) => { return 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 handleBarTouch = (e: any) => { e.origin.stopPropagation(); // 移动距离:小球的坐标位置-容器的偏移位置-小球相对容器的偏移位置-小球半径 const mouse_offset_x = e.origin.touches[0].clientX - dataSourse.containerOffset.x - e.origin.currentTarget.offsetLeft - dataSourse.bar_r; const mouse_offset_y = -( e.origin.touches[0].clientY - dataSourse.containerOffset.y - e.origin.currentTarget.offsetTop - dataSourse.bar_r ); dataSourse.mouse_offset.x = mouse_offset_x; dataSourse.mouse_offset.y = mouse_offset_y; }; 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); updateContent(radian); if (!isDrag) { return; } setCircleLocation({ ...circleLocation, left, top, }); }; 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 const angleValue = Math.floor(angle); // 0 ~ 180 const angleShow = angleValue > 180 ? 360 - angleValue : angleValue; const tempStart = dataSourse.tempValue[0]; const tempEnd = dataSourse.tempValue[1]; const { angleLimit } = dataSourse; let tempshow = (tempEnd - tempStart) / 2 + tempStart; // 中间值 角度对应0 if (angleValue < 180) { tempshow += ((tempEnd - tempshow) / angleLimit) * angleShow; } if (angleValue > 180) { tempshow -= ((tempEnd - tempshow) / angleLimit) * angleShow; } if (angleShow > angleLimit) { setIsDrag(false); return; } if (!isDrag) { setIsDrag(true); } tempshow = Math.floor(tempshow); setDataState({ ...dataState, angleValue, angleShow, tempshow, }); }; return ( {dataState.tempshow}K props.onSetDpState('temp_value', e.value)} /> {toParseInt( (dpState.temp_value / (codeMap.temp_value.property.max - codeMap.temp_value.property.min)) * 100 )} % props.onSetDpState('bright_value', e.value)} /> {toParseInt( (dpState.bright_value / (codeMap.bright_value.property.max - codeMap.bright_value.property.min)) * 100 )} % {colorArr.map(item => ( handleCirleClick(e, item)} > {item.active && -} ))} {addFlag && ( + )} ); }; export default HubCircle;