11/**
22 * @ai -context: 通用组件:TimerRing。
33 */
4- import { useRef , useEffect , useId } from 'react' ;
4+ import { useId } from 'react' ;
55import { motion } from 'framer-motion' ;
66import { cn } from '@/lib/utils' ;
77
@@ -57,8 +57,6 @@ export default function TimerRing({
5757 phase,
5858 isRunning,
5959} : TimerRingProps ) {
60- const circleRef = useRef < SVGCircleElement > ( null ) ;
61- const rafRef = useRef < number > ( 0 ) ;
6260 const gradientId = useId ( ) ;
6361 const glowGradientId = useId ( ) ;
6462
@@ -71,28 +69,10 @@ export default function TimerRing({
7169 const seconds = remainingSeconds % 60 ;
7270 const timeStr = `${ String ( minutes ) . padStart ( 2 , '0' ) } :${ String ( seconds ) . padStart ( 2 , '0' ) } ` ;
7371
74- useEffect ( ( ) => {
75- const animate = ( ) => {
76- const el = circleRef . current ;
77- if ( ! el ) return ;
78-
79- const size = window . innerWidth < 768 ? 200 : 280 ;
80- const strokeWidth = 6 ;
81- const r = ( size - strokeWidth ) / 2 ;
82- const circumference = 2 * Math . PI * r ;
83-
84- const currentProgress = totalSeconds > 0 ? remainingSeconds / totalSeconds : 0 ;
85- const offset = circumference * ( 1 - currentProgress ) ;
86-
87- el . setAttribute ( 'stroke-dasharray' , String ( circumference ) ) ;
88- el . setAttribute ( 'stroke-dashoffset' , String ( offset ) ) ;
89-
90- rafRef . current = requestAnimationFrame ( animate ) ;
91- } ;
92-
93- rafRef . current = requestAnimationFrame ( animate ) ;
94- return ( ) => cancelAnimationFrame ( rafRef . current ) ;
95- } , [ remainingSeconds , totalSeconds ] ) ;
72+ // 进度环由下方 JSX 的 strokeDashoffset prop + CSS transition(1s linear)驱动:
73+ // remainingSeconds 每秒变化触发重渲染,offset 随之平滑过渡。原 RAF 循环以 60fps
74+ // 重复 setAttribute 相同值(1h 计时约 21.6 万次无效 DOM 写)且 size 计算与 viewBox
75+ // 不一致,纯属冗余,已移除。
9676
9777 const size = 280 ;
9878 const strokeWidth = 6 ;
@@ -164,9 +144,8 @@ export default function TimerRing({
164144 className = "stroke-border/20"
165145 />
166146
167- { /* 进度环 — 带渐变 */ }
147+ { /* 进度环 — 带渐变,strokeDashoffset 变化由 CSS transition 平滑过渡 */ }
168148 < circle
169- ref = { circleRef }
170149 cx = { size / 2 }
171150 cy = { size / 2 }
172151 r = { r }
0 commit comments