@lightningjs/renderer
Version:
Lightning 3 Renderer
111 lines • 4.74 kB
JavaScript
import Transition from './Transition.js';
import { normalizeTimingFunction } from './utils.js';
import Playback, { PlaybackSettingsKeys } from './Playback.js';
const mapTransitions = (target, animationParams, aDuration, aDelay, aEasing) => {
const aStart = aDelay;
const aEnd = aDelay + aDuration;
const transitionsByKey = {};
const keys = Object.keys(animationParams);
const filteredKeys = [];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
//skip playback settings
if (PlaybackSettingsKeys[key] === true) {
continue;
}
transitionsByKey[key] = [];
filteredKeys.push(key);
}
for (let i = 0; i < filteredKeys.length; i++) {
const key = filteredKeys[i];
const prop = target[key];
if (prop === undefined) {
console.warn(`CoreAnimation: property "${key}" does not exist on target.`);
continue;
}
const aProp = animationParams[key];
if (typeof aProp === 'number') {
transitionsByKey[key].push(new Transition(null, animationParams[key], aStart, aEnd, aEasing));
continue;
}
if (typeof aProp === 'object' && Array.isArray(aProp) === false) {
const from = aProp.from ?? null;
const start = aProp.duration ?? aDuration;
const end = aDelay + (aProp.delay ?? 0);
const easing = normalizeTimingFunction(aProp.easing) ?? aEasing;
transitionsByKey[key].push(new Transition(from, aProp.to, start, end, easing));
continue;
}
const isUsableArray = Array.isArray(aProp) && aProp.length > 0;
//keyframed animation for number arrays
if (isUsableArray === true && typeof aProp[0] === 'number') {
const spreadDuration = aDuration / Math.min(aProp.length - 1, 1);
let transitionStart = aDelay;
let startValue = aProp[0];
const len = aProp.length;
if (len > 1) {
for (let j = 1; j < len; j++) {
const value = aProp[j];
const transitionEnd = transitionStart + spreadDuration;
transitionsByKey[key].push(new Transition(startValue, value, transitionStart, transitionEnd, aEasing));
//carry over to next transition
transitionStart = transitionEnd;
startValue = value;
}
}
else {
transitionsByKey[key].push(new Transition(null, startValue, transitionStart, transitionStart + spreadDuration, aEasing));
}
continue;
}
if (isUsableArray === true && typeof aProp[0] === 'string') {
console.warn(`CoreAnimation: keyframed string animations are not yet supported for property "${key}".`);
continue;
}
}
return transitionsByKey;
};
export default class Animation extends Playback {
target;
transitions;
transitionKeys;
constructor(animationManager, target, animationParams) {
super(animationManager, animationParams);
this.target = target;
this.transitions = mapTransitions(target, animationParams, this.duration, this.delay, this.easing);
this.transitionKeys = Object.keys(this.transitions);
}
updateValues(currentTime) {
for (let i = 0; i < this.transitionKeys.length; i++) {
const key = this.transitionKeys[i];
const transitions = this.transitions[key];
for (let j = 0; j < transitions.length; j++) {
const transition = transitions[j];
if (currentTime >= transition.start &&
currentTime <= transition.start + transition.end) {
//apply value to target
this.target[key] =
transition.update(currentTime);
continue;
}
}
}
}
applyStartValues() {
//set start values for transitions
for (let i = 0; i < this.transitionKeys.length; i++) {
const key = this.transitionKeys[i];
//only need to set the first transition's from value
const firstTransition = this.transitions[key][0];
const from = firstTransition.from;
const currentValue = this.target[key];
const targetValue = from !== null ? from : currentValue;
if (from === null) {
firstTransition.from = targetValue;
}
this.target[key] = targetValue;
firstTransition.currentValue = targetValue;
}
}
}
//# sourceMappingURL=Animation.js.map