package.src.animation.Clip.ts Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zrender Show documentation
Show all versions of zrender Show documentation
A lightweight graphic library providing 2d draw for Apache ECharts
The newest version!
/**
* 动画主控制器
* @config target 动画对象,可以是数组,如果是数组的话会批量分发onframe等事件
* @config life(1000) 动画时长
* @config delay(0) 动画延迟时间
* @config loop(true)
* @config onframe
* @config easing(optional)
* @config ondestroy(optional)
* @config onrestart(optional)
*
* TODO pause
*/
import easingFuncs, {AnimationEasing} from './easing';
import type Animation from './Animation';
import { isFunction, noop } from '../core/util';
import { createCubicEasingFunc } from './cubicEasing';
type OnframeCallback = (percent: number) => void;
type ondestroyCallback = () => void
type onrestartCallback = () => void
export type DeferredEventTypes = 'destroy' | 'restart'
// type DeferredEventKeys = 'ondestroy' | 'onrestart'
export interface ClipProps {
life?: number
delay?: number
loop?: boolean
easing?: AnimationEasing
onframe?: OnframeCallback
ondestroy?: ondestroyCallback
onrestart?: onrestartCallback
}
export default class Clip {
private _life: number
private _delay: number
private _inited: boolean = false
private _startTime = 0 // 开始时间单位毫秒
private _pausedTime = 0
private _paused = false
animation: Animation
loop: boolean
easing: AnimationEasing
easingFunc: (p: number) => number
// For linked list. Readonly
next: Clip
prev: Clip
onframe: OnframeCallback
ondestroy: ondestroyCallback
onrestart: onrestartCallback
constructor(opts: ClipProps) {
this._life = opts.life || 1000;
this._delay = opts.delay || 0;
this.loop = opts.loop || false;
this.onframe = opts.onframe || noop;
this.ondestroy = opts.ondestroy || noop;
this.onrestart = opts.onrestart || noop;
opts.easing && this.setEasing(opts.easing);
}
step(globalTime: number, deltaTime: number): boolean {
// Set startTime on first step, or _startTime may has milleseconds different between clips
// PENDING
if (!this._inited) {
this._startTime = globalTime + this._delay;
this._inited = true;
}
if (this._paused) {
this._pausedTime += deltaTime;
return;
}
const life = this._life;
let elapsedTime = globalTime - this._startTime - this._pausedTime;
let percent = elapsedTime / life;
// PENDING: Not begin yet. Still run the loop.
// In the case callback needs to be invoked.
// Or want to update to the begin state at next frame when `setToFinal` and `delay` are both used.
// To avoid the unexpected blink.
if (percent < 0) {
percent = 0;
}
percent = Math.min(percent, 1);
const easingFunc = this.easingFunc;
const schedule = easingFunc ? easingFunc(percent) : percent;
this.onframe(schedule);
// 结束
if (percent === 1) {
if (this.loop) {
// Restart
const remainder = elapsedTime % life;
this._startTime = globalTime - remainder;
this._pausedTime = 0;
this.onrestart();
}
else {
return true;
}
}
return false;
}
pause() {
this._paused = true;
}
resume() {
this._paused = false;
}
setEasing(easing: AnimationEasing) {
this.easing = easing;
this.easingFunc = isFunction(easing)
? easing
: easingFuncs[easing] || createCubicEasingFunc(easing);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy