@egjs/view3d
Version:
Fast & Customizable glTF 3D model viewer, packed with full of features!
104 lines (86 loc) • 2.85 kB
text/typescript
/*
* Copyright (c) 2020 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
import { clamp, lerp, circulate } from "../utils";
import * as DEFAULT from "../const/default";
import { Range } from "../type/utils";
class Motion {
// Options
private _duration: number;
private _loop: boolean;
private _range: Range;
private _easing: (x: number) => number;
// Internal states
private _progress: number;
private _val: number;
private _start: number;
private _end: number;
private _activated: boolean;
public get val() { return this._val; }
public get start() { return this._start; }
public get end() { return this._end; }
public get progress() { return this._progress; }
public get duration() { return this._duration; }
public get loop() { return this._loop; }
public get range() { return this._range; }
public get easing() { return this._easing; }
public get activated() { return this._activated; }
public set duration(val: number) { this._duration = val; }
public set loop(val: boolean) { this._loop = val; }
public set range(val: Range) { this._range = val; }
public set easing(val: (x: number) => number) { this._easing = val; }
public constructor({
duration = DEFAULT.ANIMATION_DURATION,
loop = DEFAULT.ANIMATION_LOOP,
range = DEFAULT.ANIMATION_RANGE,
easing = DEFAULT.EASING
} = {}) {
this._duration = duration;
this._loop = loop;
this._range = range;
this._easing = easing;
this._activated = false;
this.reset(0);
}
/**
* Update motion and progress it by given deltaTime
* @param deltaTime number of milisec to update motion
* @returns Difference(delta) of the value from the last update.
*/
public update(deltaTime: number): number {
if (!this._activated) return 0;
const start = this._start;
const end = this._end;
const duration = this._duration;
const prev = this._val;
const loop = this._loop;
const nextProgress = this._progress + deltaTime / duration;
this._progress = loop
? circulate(nextProgress, 0, 1)
: clamp(nextProgress, 0, 1);
const easedProgress = this._easing(this._progress);
this._val = lerp(start, end, easedProgress);
if (!loop && this._progress >= 1) {
this._activated = false;
}
return this._val - prev;
}
public reset(defaultVal: number): void {
const range = this._range;
const val = clamp(defaultVal, range.min, range.max);
this._start = val;
this._end = val;
this._val = val;
this._progress = 0;
this._activated = false;
}
public setEndDelta(delta: number): void {
const range = this._range;
this._start = this._val;
this._end = clamp(this._end + delta, range.min, range.max);
this._progress = 0;
this._activated = true;
}
}
export default Motion;