@@ -19,7 +19,6 @@ interface Particle {
1919 phi : number ;
2020 r : number ;
2121 speed : number ;
22- phase : number ;
2322}
2423
2524interface ChronosDemoProps {
@@ -44,6 +43,13 @@ export function ChronosDemo({ controlledState = null, onStateChange }: ChronosDe
4443 onStateChange ?.( next ) ;
4544 } ;
4645
46+ const handleKeyDown = ( e : React . KeyboardEvent < HTMLDivElement > ) => {
47+ if ( e . key === "Enter" || e . key === " " ) {
48+ e . preventDefault ( ) ;
49+ handleTap ( ) ;
50+ }
51+ } ;
52+
4753 useEffect ( ( ) => {
4854 const canvas = canvasRef . current ;
4955 if ( ! canvas ) return ;
@@ -53,6 +59,7 @@ export function ChronosDemo({ controlledState = null, onStateChange }: ChronosDe
5359 const reduced = window . matchMedia ( "(prefers-reduced-motion: reduce)" ) . matches ;
5460 const dpr = Math . min ( window . devicePixelRatio || 1 , 2 ) ;
5561 const size = Math . min ( canvas . clientWidth , canvas . clientHeight ) ;
62+ if ( size === 0 ) return ; // 容器不可见时跳过初始化
5663 canvas . width = size * dpr ;
5764 canvas . height = size * dpr ;
5865 ctx . scale ( dpr , dpr ) ;
@@ -63,7 +70,6 @@ export function ChronosDemo({ controlledState = null, onStateChange }: ChronosDe
6370 phi : Math . acos ( 2 * Math . random ( ) - 1 ) ,
6471 r : 0.55 + Math . random ( ) * 0.45 ,
6572 speed : 0.05 + Math . random ( ) * 0.12 ,
66- phase : Math . random ( ) * Math . PI * 2 ,
6773 } ) ) ;
6874
6975 const cx = size / 2 ;
@@ -155,7 +161,9 @@ export function ChronosDemo({ controlledState = null, onStateChange }: ChronosDe
155161 < div
156162 className = "relative w-[clamp(240px,52vmin,420px)] h-[clamp(240px,52vmin,420px)] mx-auto cursor-pointer select-none"
157163 onClick = { handleTap }
164+ onKeyDown = { handleKeyDown }
158165 role = "button"
166+ tabIndex = { 0 }
159167 aria-label = "Chronos 时间生物演示,点击切换形态"
160168 >
161169 < canvas ref = { canvasRef } className = "w-full h-full" />
0 commit comments