Ghiduri · 06
Cronologii Rulați multe piste de pe un singur ceas cu derulare: redare, pauză, salt, inversare și schimbare de viteză.
Piste pe un singur ceas useTimeline(tracks, options, deps) creează o cronologie deținută de componentă. Fiecare pistă este o listă de keyframe-uri sau { values, times, at, duration }, cu at și duration în milisecunde.
progress este o singură variabilă CSS, iar pistele numerice sau de lungime sunt expresii calc() ale ei, așa că o cronologie în stilul obișnuit scrie o variabilă per cadru.
JavaScript este dezactivat. Codul de mai jos este exemplul complet.
App.jsx import { useRef } from 'react' ;
import { useTimeline } from '@kkwaenggwari/animated' ;
import './styles.css' ;
export default function App ({ duration = 3000 , repeat = true } ) {
const timeline = useTimeline (
{
x : ['0px' , '220px' , '220px' , '0px' , '0px' ],
y : ['0px' , '0px' , '110px' , '110px' , '0px' ],
turn : ['0deg' , '90deg' , '180deg' , '270deg' , '360deg' ],
round : ['50%' , '12%' , '50%' , '12%' , '50%' ],
},
{ duration, repeat : repeat ? Infinity : 0 },
[duration, repeat],
);
const bar = useRef (null );
const seek = (event ) => {
const box = bar.current .getBoundingClientRect ();
const ratio = Math .min (1 , Math .max (0 , (event.clientX - box.left ) / box.width ));
timeline.pause ();
timeline.seek (ratio * timeline.duration );
};
const { x, y, turn, round } = timeline.values ;
return (
<div className ="stage" >
<div className ="canvas" >
<span
className ="shape"
style ={{ transform: `translate (${x }, ${y }) rotate (${turn })`, borderRadius: round }}
/>
</div >
<div className ="player" >
<button type ="button" onClick ={() => timeline.play()}>
Play
</button >
<button type ="button" onClick ={() => timeline.pause()}>
Pause
</button >
<div
ref ={bar}
className ="scrub"
onPointerDown ={(event) => {
event.currentTarget.setPointerCapture(event.pointerId);
seek(event);
}}
onPointerMove={(event) => {
if (event.buttons) seek(event);
}}
>
<span style ={{ transform: `scaleX (${timeline.progress })` }} />
</div >
</div >
</div >
);
}styles.css .stage {
display : grid;
gap : 16px ;
padding : 28px ;
}
.canvas {
height : 190px ;
padding : 20px ;
border-radius : 16px ;
background : #0b1440 ;
}
.shape {
display : block;
width : 60px ;
height : 60px ;
background : #5c7cff ;
}
.player {
display : flex;
align-items : center;
gap : 8px ;
}
.player button {
min-height : 40px ;
padding : 0 16px ;
border : 1px solid #e4e6ef ;
border-radius : 999px ;
background : #fff ;
font : inherit;
cursor : pointer;
}
.scrub {
flex : 1 ;
height : 12px ;
border-radius : 999px ;
background : #eef2ff ;
overflow : hidden;
cursor : pointer;
touch-action : none;
}
.scrub span {
display : block;
height : 100% ;
background : #2854ff ;
transform-origin : left center;
}Controlul redării play({ from, rate }), pause(), seek(ms) și reverse() controlează ceasul. state, currentTime, duration și promise-ul finished îl descriu. repeat și repeatDelay îl repetă.
Title.jsx Copiază codul const intro = useTimeline (
{
y : ['24px' , '0px' ],
fade : { values : [0 , 1 ], at : 0 , duration : 300 },
line : { values : [0 , 1 ], at : 200 , duration : 600 },
},
{ duration : 800 },
);
intro.seek (400 );
intro.play ({ rate : 0.5 });
intro.reverse ();În afara React createTimeline este același ceas fără componentă. Apelați dispose() când ați terminat.