@lightningjs/renderer
Version:
Lightning 3 Renderer
155 lines • 5.35 kB
JavaScript
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 Comcast Cable Communications Management, LLC.
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from '../../common/EventEmitter.js';
import { normalizeTimingFunction } from './utils.js';
export var StopMethodFlags;
(function (StopMethodFlags) {
StopMethodFlags[StopMethodFlags["Immediate"] = 0] = "Immediate";
StopMethodFlags[StopMethodFlags["Reset"] = 1] = "Reset";
StopMethodFlags[StopMethodFlags["Reverse"] = 2] = "Reverse";
})(StopMethodFlags || (StopMethodFlags = {}));
export const getStopMethodFlag = (method) => {
if (method === undefined || method === 'immediate') {
return StopMethodFlags.Immediate;
}
switch (method) {
case 'reverse':
return StopMethodFlags.Reverse;
case 'reset':
return StopMethodFlags.Reset;
}
return StopMethodFlags.Immediate;
};
export var PlaybackState;
(function (PlaybackState) {
PlaybackState[PlaybackState["Idle"] = 0] = "Idle";
PlaybackState[PlaybackState["Destroyed"] = 1] = "Destroyed";
PlaybackState[PlaybackState["Stopped"] = 2] = "Stopped";
PlaybackState[PlaybackState["Finished"] = 3] = "Finished";
PlaybackState[PlaybackState["Paused"] = 4] = "Paused";
PlaybackState[PlaybackState["Playing"] = 5] = "Playing";
PlaybackState[PlaybackState["Stopping"] = 6] = "Stopping";
})(PlaybackState || (PlaybackState = {}));
export const PlaybackSettingsKeys = {
delay: true,
duration: true,
easing: true,
loop: true,
repeat: true,
reverse: true,
stopMethod: true,
};
//freeze the keys object to prevent modification
Object.freeze(PlaybackSettingsKeys);
/**
* Returns a new unique ID
*/
let playbackId = 1;
export function getPlaybackId() {
return playbackId++;
}
export default class Playback extends EventEmitter {
animationManager;
//id
id = getPlaybackId();
//settings
delay;
duration;
easing;
loop;
repeat;
reverse;
stopMethod;
//lifecycle
state = PlaybackState.Idle;
startTime = null;
pauseTime = null;
endTime = null;
currentTime = 0;
iteration = 0;
constructor(animationManager, settings = {}) {
super();
this.animationManager = animationManager;
this.delay = settings.delay ?? 0;
this.duration = settings.duration ?? 200;
this.easing = normalizeTimingFunction(settings.easing);
this.loop = settings.loop ?? false;
this.repeat = settings.repeat ?? 0;
this.reverse = settings.reverse ?? false;
this.stopMethod = getStopMethodFlag(settings.stopMethod);
}
update(currentFrameTime) {
let state = this.state;
let targetTime = currentFrameTime - this.startTime;
if (state === PlaybackState.Stopping) {
targetTime = this.duration - targetTime;
}
if (state === PlaybackState.Playing && targetTime > this.duration) {
targetTime = this.duration;
if (this.loop === true) {
this.iteration++;
this.startTime = currentFrameTime;
targetTime = 0;
if (this.repeat > 0 && this.iteration > this.repeat) {
this.stop();
}
}
}
}
updateValues(currentTime) { }
applyStartValues() {
//needs to be implemented in subclass
}
start() {
const animationManager = this.animationManager;
this.startTime = animationManager.currentFrameTime + this.delay;
this.endTime = this.startTime + this.duration;
this.state = PlaybackState.Playing;
animationManager.register(this);
this.emit('start');
return this;
}
stop() {
const stopMethod = this.stopMethod;
if (stopMethod === StopMethodFlags.Immediate) {
this.finish();
return;
}
if (stopMethod === StopMethodFlags.Reset) {
this.updateValues(0);
this.finish();
return;
}
if (stopMethod === StopMethodFlags.Reverse) {
if (this.state === PlaybackState.Playing) {
this.state = PlaybackState.Stopping;
//adjust start time to account for current time
const currentFrameTime = this.animationManager.currentFrameTime;
const elapsedTime = currentFrameTime - this.startTime;
this.startTime = currentFrameTime - (this.duration - elapsedTime);
}
}
}
finish() {
this.state = PlaybackState.Finished;
this.emit('finish');
this.animationManager.unregister(this);
}
}
//# sourceMappingURL=Playback.js.map