123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // @ts-nocheck
- import {raf, cancelRaf} from '../raf'
- export class Timeline {
- state : string
- animations : Set<Animation> = new Set<Animation>()
- delAnimations : Animation[] = []
- startTimes : Map<Animation, number> = new Map<Animation, number>()
- pauseTime : number = 0
- pauseStart : number = Date.now()
- tickHandler : number = 0
- tickHandlers : number[] = []
- tick : (() => void) | null = null
- constructor() {
- this.state = 'Initiated';
- }
- start() {
- if (!(this.state === 'Initiated')) return;
- this.state = 'Started';
- let startTime = Date.now();
- this.pauseTime = 0;
- this.tick = () => {
- let now = Date.now();
- this.animations.forEach((animation : Animation) => {
- let t:number;
- const ani = this.startTimes.get(animation)
- if (ani == null) return
- if (ani < startTime) {
- t = now - startTime - animation.delay - this.pauseTime;
- } else {
- t = now - ani - animation.delay - this.pauseTime;
- }
- if (t > animation.duration) {
- this.delAnimations.push(animation)
- // 不能在 foreach 里面 对 集合进行删除操作
- // this.animations.delete(animation);
- t = animation.duration;
- }
- if (t > 0) animation.run(t);
- })
- // 不能在 foreach 里面 对 集合进行删除操作
- while (this.delAnimations.length > 0) {
- const animation = this.delAnimations.pop();
- if (animation == null) return
- this.animations.delete(animation);
- }
- clearTimeout(this.tickHandler);
- if (this.state != 'Started') return
- // this.tickHandler = setTimeout(() => {
- // this.tick!()
- // }, 1000 / 60)
- this.tickHandler = raf(()=> {
- this.tick!()
- })
- // this.tickHandlers.push(this.tickHandler)
- }
- this.tick!()
- }
- pause() {
- if (!(this.state === 'Started')) return;
- this.state = 'Paused';
- this.pauseStart = Date.now();
- // clearTimeout(this.tickHandler);
- cancelRaf(this.tickHandler);
- }
- resume() {
- if (!(this.state === 'Paused')) return;
- this.state = 'Started';
- this.pauseTime += Date.now() - this.pauseStart;
- this.tick!();
- }
- reset() {
- this.pause();
- this.state = 'Initiated';
- this.pauseTime = 0;
- this.pauseStart = 0;
- this.animations.clear()
- this.delAnimations.clear()
- this.startTimes.clear()
- this.tickHandler = 0;
- }
- add(animation : Animation, startTime ?: number | null) {
- if (startTime == null) startTime = Date.now();
- this.animations.add(animation);
- this.startTimes.set(animation, startTime);
- }
- }
- export class Animation {
- startValue : number
- endValue : number
- duration : number
- timingFunction : (t : number) => number
- delay : number
- template : (t : number) => void
- constructor(
- startValue : number,
- endValue : number,
- duration : number,
- delay : number,
- timingFunction : (t : number) => number,
- template : (v : number) => void) {
- this.startValue = startValue;
- this.endValue = endValue;
- this.duration = duration;
- this.timingFunction = timingFunction;
- this.delay = delay;
- this.template = template;
- }
- run(time : number) {
- let range = this.endValue - this.startValue;
- let progress = time / this.duration
- if(progress != 1) progress = this.timingFunction(progress)
- this.template(this.startValue + range * progress)
- }
- }
|