@lightningjs/renderer
Version:
Lightning 3 Renderer
194 lines • 6.99 kB
JavaScript
import { createTransition, } from './Transition.js';
import { normalizeTimingFunction } from './utils.js';
import Playback, { PlaybackSettingsKeys } from './Playback.js';
const mapTransitions = (target, animationParams, aDuration, aEasing) => {
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);
}
aEasing = aEasing ?? undefined;
//only initialize these values when needed to avoid unnecessary workload
let easing;
let delay;
let duration;
let to;
let from;
let start;
let end;
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(createTransition({
to: aProp,
from: undefined,
start: 0,
end: aDuration,
delay: 0,
duration: aDuration,
easing: aEasing,
}));
continue;
}
easing = aEasing;
if (typeof aProp === 'object' && Array.isArray(aProp) === false) {
delay = aProp.delay ?? 0;
duration = aProp.duration ?? aDuration;
from = aProp.from;
start = delay;
end = start + duration;
easing =
aProp.easing !== undefined
? normalizeTimingFunction(aProp.easing) ?? easing
: easing;
transitionsByKey[key].push(createTransition({
to: aProp.to,
from: from,
start,
end,
delay,
duration,
easing,
}));
continue;
}
//keyframed animation
let frame;
const isUsableArray = Array.isArray(aProp) && aProp.length > 0;
//keyframed animation for number arrays
if (isUsableArray === true) {
const spreadDuration = aDuration / Math.max(aProp.length - 1, 1);
start = 0;
let startValue = aProp[0];
if (typeof startValue === 'object') {
frame = aProp[0];
startValue = frame.to;
to = startValue;
from = frame.from;
duration = frame.duration ?? aDuration;
delay = frame.delay ?? 0;
easing =
frame.easing !== undefined
? normalizeTimingFunction(frame.easing) ?? easing
: easing;
}
else {
to = startValue;
from = startValue;
duration = aDuration;
delay = 0;
}
start = delay;
end = start + duration;
const len = aProp.length;
if (len > 1) {
for (let j = 1; j < len; j++) {
const value = aProp[j];
if (typeof value === 'object') {
frame = value;
to = frame.to;
from = startValue;
duration = frame.duration ?? spreadDuration;
delay = frame.delay ?? 0;
easing =
frame.easing !== undefined
? normalizeTimingFunction(frame.easing) ?? easing
: easing;
}
else {
to = value;
from = startValue;
duration = spreadDuration;
delay = 0;
}
start = start + delay;
end = start + duration;
transitionsByKey[key].push(createTransition({
to,
from,
start,
end,
delay,
duration,
easing,
}));
//carry over to next transition
start = end;
startValue = to;
}
}
else {
transitionsByKey[key].push(createTransition({
to,
from,
start,
end,
delay,
duration,
easing,
}));
}
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.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.end) {
//apply value to target
this.target[key] =
transition.update(currentTime - transition.start);
continue;
}
}
}
}
applyStartValues() {
//set start values for transitions
for (let i = 0; i < this.transitionKeys.length; i++) {
const key = this.transitionKeys[i];
const transitionsByKey = this.transitions[key];
//only need to set the first transition's from value
const firstTransition = transitionsByKey[0];
const from = firstTransition.from;
if (from !== undefined) {
this.target[key] = from;
firstTransition.current = from;
firstTransition.from = from;
continue;
}
const currentValue = this.target[key];
firstTransition.from = currentValue;
firstTransition.current = currentValue;
}
}
}
//# sourceMappingURL=Animation.js.map