import { Canvas } from "@tarojs/components"; import Taro from "@tarojs/taro"; import { useDidShow, useReady } from "@tarojs/taro"; import { useEffect, useRef, useState } from "react"; import { useSelector } from "react-redux"; export type RingCommon = { useCase: string; status: string; isFast?: boolean; radius: number; lineWidth: number; } export type CurrentDot = { color: string; lineWidth: number; borderColor: string; timestamp?:number; } export type RealRing = { color: string; startArc: number; durationArc: number; } export type TargetRing = { color: string; startArc: number; durationArc: number; } export type BgRing = { color: string; } export default function Rings(props: { common: RingCommon; currentDot?: CurrentDot; realRing?: RealRing; targetRing?: TargetRing; breathAnimation?:boolean; bgRing: BgRing; canvasId?: string; ctx?:any; setCtx?:any; canvas?:any; setCanvas?:any; dotList?:Array; stageList?:Array; }) { const r = props.common.radius const strokeWidth = props.common.lineWidth; // const color = props.color || 'orange' const canvasRef = useRef(null); const canvasId = props.canvasId ? 'canvas_' + props.canvasId : 'progress-canvas'; const dpr = Taro.getSystemInfoSync().pixelRatio; // 获取设备的像素比 const radius = r; // 圆形进度条的半径 const lineWidth = strokeWidth; // 圆形进度条的线宽 const time = useSelector((state: any) => state.time); const user = useSelector((state: any) => state.user); useEffect(()=>{ // drawCircle() },[]) useReady(() => { drawCircle() }) useEffect(() => { if (props.ctx){ drawContent(props.ctx) } else { drawCircle() } }, [time.status,time.scenario,user.isLogin,props.targetRing, props.currentDot,props.realRing,props.currentDot?.color,props.canvasId]); useEffect(()=>{ // if (props.breathAnimation){ // animation() // } // else { // global.breathAlpha = 1 // animation() // } },[props.breathAnimation]) function animation(){ const duration = 1000; // 动画执行时间(毫秒) let animationId: number | null = null; let startTime: number | null = null; const animate = (timestamp: number) => { if (!startTime) { startTime = timestamp; } const elapsed = timestamp - startTime; const progress = elapsed / duration; // 动画进度(0 到 1) global.breathAlpha = progress if (elapsed < duration) { animationId = requestAnimationFrame(animate); } else { // 动画完成后重新开始 startTime = null; animationId = requestAnimationFrame(animate); } } animationId = requestAnimationFrame(animate); } function drawCircle() { const query = Taro.createSelectorQuery(); query.select(`.${canvasId}`).fields({ node: true, size: true }); query.exec((res) => { if (props.canvasId=='hello'){ debugger } if (res[0] == null) { drawCircle() return; } const _canvas = res[0].node; _canvas.width = res[0].width * dpr; _canvas.height = res[0].height * dpr; const ctx = _canvas.getContext('2d'); if (props.setCtx){ props.setCtx(ctx) props.setCanvas(_canvas) drawContent(ctx) } else { drawContent(ctx) } // setCanvas(_canvas) // setContext(ctx) // const ctx = Taro.createCanvasContext(canvasId); // drawContent(ctx) }); } function calculateCoordinates(x, y, r, angle) { const radians = angle * Math.PI / 180; // 将角度转换为弧度 const xPrime = x + r * Math.cos(radians); const yPrime = y + r * Math.sin(radians); return { x: xPrime, y: yPrime }; } function drawContent(ctx){ if (props.canvas){ props.canvas.width = ((radius * 2 + lineWidth)+6) * dpr; props.canvas.height = ((radius * 2 + lineWidth)+6) * dpr; } const center = radius + lineWidth / 2+3; // 圆心坐标 ctx.clearRect(0, 0, radius * 2, radius * 2); // 清除画布 // 设置画布尺寸 ctx.scale(dpr, dpr); // 绘制背景圆 ctx.beginPath(); ctx.arc(center, center, radius, 0, 2 * Math.PI); ctx.lineWidth = lineWidth; ctx.strokeStyle = props.bgRing.color; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); // 绘制target进度环 if (props.targetRing) { ctx.beginPath(); ctx.arc(center, center, radius, props.targetRing!.startArc, props.targetRing!.startArc + props.targetRing!.durationArc); ctx.lineWidth = lineWidth; ctx.strokeStyle = props.targetRing!.color; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); } //绘制real进度环 if (props.realRing) { if (props.realRing.durationArc <0.01) props.realRing.durationArc=0.01; ctx.beginPath(); ctx.arc(center, center, radius, props.realRing!.startArc, props.realRing!.startArc + props.realRing!.durationArc); ctx.lineWidth = lineWidth; ctx.strokeStyle = props.realRing!.color; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); } if (props.stageList){ props.stageList.map(item=>{ if (item.durationArc <0.01) item.durationArc=0.01; ctx.beginPath(); ctx.arc(center, center, radius, item.startArc, item.startArc + item.durationArc); ctx.lineWidth = lineWidth; ctx.strokeStyle = item.color; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); }) } //绘制current_dot点 if (props.currentDot) { var time = new Date(); var seconds = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds(); var arc = seconds / 86400 * 2 * Math.PI - Math.PI / 2.0; const radians = arc;//angle * Math.PI / 180; // 将角度转换为弧度 const xPrime = center + r * Math.cos(radians); const yPrime = center + r * Math.sin(radians); ctx.beginPath(); var dotLineWidth = 2 if (lineWidth==28){ dotLineWidth = 4 } ctx.arc(xPrime, yPrime, lineWidth/2.0+dotLineWidth/2.0, 0, 2 * Math.PI); ctx.lineWidth = dotLineWidth; ctx.strokeStyle = '#1C1C1C'; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); // ctx.beginPath(); // ctx.arc(center, center, radius, arc, // arc + 0.001); // ctx.lineWidth = lineWidth+6; // ctx.strokeStyle = props.currentDot!.borderColor; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // ctx.save() // ctx.beginPath(); // ctx.arc(center, center, radius, arc, // arc + 0.001); // ctx.lineWidth = lineWidth; // ctx.strokeStyle = props.currentDot!.color; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // ctx.restore() } if (props.dotList){ props.dotList.map(item=>{ var time = item.timestamp?new Date(item.timestamp):new Date(); var seconds = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds(); var arc = seconds / 86400 * 2 * Math.PI - Math.PI / 2.0; ctx.beginPath(); ctx.arc(center, center, radius, arc, arc + 0.001); ctx.lineWidth = lineWidth+6; ctx.strokeStyle = item.borderColor; ctx.lineCap = 'round'; // 设置为圆角 ctx.stroke(); ctx.save() ctx.beginPath(); ctx.arc(center, center, radius, arc, arc + 0.001); ctx.lineWidth = lineWidth; ctx.strokeStyle = item.color; ctx.lineCap = 'round'; // 设置为圆角 // ctx.globalAlpha = global.breathAlpha ctx.stroke(); ctx.restore() }) } } return } // export default function Rings(props: { // common: RingCommon; currentDot?: CurrentDot; // realRing?: RealRing; targetRing?: TargetRing; bgRing: BgRing; canvasId?: string;test?:boolean // }) { // const r = props.common.radius // const strokeWidth = props.common.lineWidth; // // const color = props.color || 'orange' // const canvasRef = useRef(null); // const canvasId = props.canvasId ? 'canvas_' + props.canvasId : 'progress-canvas'; // const dpr = Taro.getSystemInfoSync().pixelRatio; // 获取设备的像素比 // const radius = r; // 圆形进度条的半径 // const lineWidth = strokeWidth; // 圆形进度条的线宽 // useDidShow(() => { // // drawCircle() // }) // useReady(() => { // drawCircle() // }) // function drawCircle() { // const query = Taro.createSelectorQuery(); // query.select(`.${canvasId}`).fields({ node: true, size: true }); // query.exec((res) => { // if (res[0] == null) return; // const _canvas = res[0].node; // _canvas.width = res[0].width * dpr; // _canvas.height = res[0].height * dpr; // const ctx = _canvas.getContext('2d'); // // const ctx = Taro.createCanvasContext(canvasId); // const center = radius + lineWidth / 2; // 圆心坐标 // ctx.clearRect(0, 0, radius * 2, radius * 2); // 清除画布 // // 设置画布尺寸 // ctx.scale(dpr, dpr); // // 绘制背景圆 // ctx.beginPath(); // ctx.arc(center, center, radius, 0, 2 * Math.PI); // ctx.lineWidth = lineWidth; // ctx.strokeStyle = props.bgRing.color; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // // 绘制target进度环 // if (props.common.useCase == 'ChooseScenario' || (props.common.useCase == 'Clock' && props.targetRing)) { // ctx.beginPath(); // ctx.arc(center, center, radius, props.targetRing!.startArc, // props.targetRing!.startArc + props.targetRing!.durationArc); // ctx.lineWidth = lineWidth; // ctx.strokeStyle = props.targetRing!.color; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // } // //绘制real进度环 // if (props.common.status != 'WAIT_FOR_START' && props.realRing) { // ctx.beginPath(); // ctx.arc(center, center, radius, props.realRing!.startArc, // props.realRing!.startArc + props.realRing!.durationArc); // ctx.lineWidth = lineWidth; // ctx.strokeStyle = props.realRing!.color; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // } // //绘制current_dot点 // if (props.common.useCase == 'Clock') { // var time = new Date(); // var seconds = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds(); // var arc = seconds / 86400 * 2 * Math.PI - Math.PI / 2.0; // ctx.beginPath(); // ctx.arc(center, center, radius, arc, // arc + 0.001); // ctx.lineWidth = lineWidth; // ctx.strokeStyle = props.currentDot!.borderColor; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // ctx.beginPath(); // ctx.arc(center, center, radius, arc, // arc + 0.001); // ctx.lineWidth = lineWidth - 2; // ctx.strokeStyle = props.currentDot!.color; // ctx.lineCap = 'round'; // 设置为圆角 // ctx.stroke(); // } // // ctx.draw(); // }); // } // useEffect(() => { // drawCircle() // }, [props.targetRing, props.currentDot]); // return // }