2020-07-13 09:29:16 +00:00
|
|
|
import * as loader from "./loader/loader";
|
|
|
|
import {Stage} from "./loader/loader";
|
2021-03-18 17:59:06 +00:00
|
|
|
import {getUrlParameter} from "./loader/Utils";
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
let overlay: HTMLDivElement;
|
|
|
|
let setupContainer: HTMLDivElement;
|
2020-10-04 18:47:19 +00:00
|
|
|
let idleNormalContainer: HTMLDivElement;
|
|
|
|
let idleNormalSteamContainer: HTMLDivElement;
|
|
|
|
let idleHalloweenContainer: HTMLDivElement;
|
2020-07-13 09:29:16 +00:00
|
|
|
let loaderStageContainer: HTMLDivElement;
|
|
|
|
|
|
|
|
let finalizing = false;
|
|
|
|
let initializeTimestamp;
|
|
|
|
|
|
|
|
let verbose = false;
|
|
|
|
let apngSupport = undefined;
|
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
let loopInterval: number;
|
|
|
|
let animationType: "normal" | "halloween";
|
|
|
|
|
2020-07-13 09:29:16 +00:00
|
|
|
async function detectAPNGSupport() {
|
|
|
|
const image = new Image();
|
|
|
|
const ctx = document.createElement("canvas").getContext("2d");
|
|
|
|
|
|
|
|
// frame 1 (skipped on apng-supporting browsers): [0, 0, 0, 255]
|
|
|
|
// frame 2: [0, 0, 0, 0]
|
|
|
|
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==";
|
|
|
|
await new Promise(resolve => image.onload = resolve);
|
|
|
|
|
|
|
|
ctx.drawImage(image, 0, 0);
|
|
|
|
apngSupport = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initializeElements() {
|
|
|
|
overlay = document.getElementById("loader-overlay") as HTMLDivElement;
|
2020-10-04 18:47:19 +00:00
|
|
|
if(!overlay) {
|
2020-07-13 09:29:16 +00:00
|
|
|
throw "missing loader overlay";
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
for(const lazyImage of [...overlay.getElementsByTagName("lazy-img")]) {
|
2020-10-04 18:47:19 +00:00
|
|
|
if(lazyImage.hasAttribute("x-animation-depend") && lazyImage.getAttribute("x-animation-depend") !== animationType) {
|
|
|
|
lazyImage.remove();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-07-13 09:29:16 +00:00
|
|
|
const image = document.createElement("img");
|
|
|
|
image.alt = lazyImage.getAttribute("alt");
|
|
|
|
image.src = lazyImage.getAttribute(apngSupport ? "src-apng" : "src-gif") || lazyImage.getAttribute("src");
|
|
|
|
image.className = lazyImage.className;
|
2020-07-17 21:56:20 +00:00
|
|
|
image.draggable = false;
|
2020-07-13 09:29:16 +00:00
|
|
|
lazyImage.replaceWith(image);
|
|
|
|
}
|
|
|
|
|
|
|
|
setupContainer = overlay.getElementsByClassName("setup")[0] as HTMLDivElement;
|
2020-10-04 18:47:19 +00:00
|
|
|
if(!setupContainer) {
|
2020-07-13 09:29:16 +00:00
|
|
|
throw "missing setup container";
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
idleNormalContainer = overlay.getElementsByClassName("idle animation-normal")[0] as HTMLDivElement;
|
|
|
|
if(!idleNormalContainer) {
|
|
|
|
throw "missing normal idle container";
|
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
idleHalloweenContainer = overlay.getElementsByClassName("idle animation-halloween")[0] as HTMLDivElement;
|
|
|
|
if(!idleHalloweenContainer) {
|
|
|
|
throw "missing halloween idle container";
|
|
|
|
}
|
|
|
|
|
|
|
|
idleNormalSteamContainer = idleNormalContainer.getElementsByClassName("steam")[0] as HTMLDivElement;
|
|
|
|
if(!idleNormalSteamContainer) {
|
|
|
|
throw "missing normal idle steam container";
|
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
loaderStageContainer = overlay.getElementsByClassName("loader-stage")[0] as HTMLDivElement;
|
2020-10-04 18:47:19 +00:00
|
|
|
if(!loaderStageContainer) {
|
2020-07-13 09:29:16 +00:00
|
|
|
throw "missing loader stage container";
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
setupContainer.onanimationend = setupAnimationFinished;
|
2020-10-04 18:47:19 +00:00
|
|
|
idleHalloweenContainer.onanimationiteration = idleSteamAnimationLooped;
|
|
|
|
idleNormalSteamContainer.onanimationiteration = idleSteamAnimationLooped;
|
2020-07-13 09:29:16 +00:00
|
|
|
overlay.onanimationend = overlayAnimationFinished;
|
|
|
|
}
|
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
export async function initialize(customLoadingAnimations: boolean) {
|
|
|
|
if(customLoadingAnimations) {
|
|
|
|
const now = new Date();
|
|
|
|
/* Note, the months start with zero */
|
|
|
|
if(now.getMonth() === 9) {
|
|
|
|
animationType = "halloween";
|
2020-11-10 15:16:51 +00:00
|
|
|
} else if(now.getMonth() === 10 && now.getDate() <= 5) {
|
2020-10-04 18:47:19 +00:00
|
|
|
animationType = "halloween";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!animationType) {
|
|
|
|
animationType = "normal";
|
|
|
|
}
|
|
|
|
|
2020-07-13 09:29:16 +00:00
|
|
|
await detectAPNGSupport();
|
|
|
|
try {
|
|
|
|
initializeElements();
|
|
|
|
} catch (error) {
|
|
|
|
console.error("Failed to setup animations: %o", error);
|
|
|
|
loader.critical_error("Animation setup failed", error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
StageNames[Stage.SETUP] = "starting app";
|
|
|
|
StageNames[Stage.TEMPLATES] = "loading templates";
|
|
|
|
StageNames[Stage.STYLE] = "loading styles";
|
|
|
|
StageNames[Stage.JAVASCRIPT] = "loading app";
|
|
|
|
StageNames[Stage.JAVASCRIPT_INITIALIZING] = "initializing";
|
|
|
|
StageNames[Stage.FINALIZING] = "rounding up";
|
|
|
|
StageNames[Stage.LOADED] = "starting app";
|
|
|
|
|
|
|
|
overlay.classList.add("initialized");
|
2020-08-09 16:58:19 +00:00
|
|
|
|
|
|
|
if(parseInt(getUrlParameter("animation-short")) === 1) {
|
|
|
|
setupAnimationFinished();
|
|
|
|
} else {
|
2020-10-04 18:47:19 +00:00
|
|
|
setupContainer.classList.add("visible", animationType);
|
2020-08-09 16:58:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
initializeTimestamp = Date.now();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function abort() {
|
|
|
|
overlay?.remove();
|
2020-10-04 18:47:19 +00:00
|
|
|
clearInterval(loopInterval);
|
|
|
|
loopInterval = 0;
|
2020-07-13 09:29:16 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 08:44:44 +00:00
|
|
|
export function finalize(abortAnimation: boolean) {
|
|
|
|
if(abortAnimation) {
|
2020-07-20 17:08:13 +00:00
|
|
|
abort();
|
|
|
|
} else {
|
|
|
|
finalizing = true;
|
2020-07-13 09:29:16 +00:00
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
if(loaderStageContainer) {
|
2020-07-20 17:08:13 +00:00
|
|
|
loaderStageContainer.innerText = "app loaded successfully (" + (Date.now() - initializeTimestamp) + "ms)";
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-20 17:08:13 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const StageNames = {};
|
|
|
|
export function updateState(state: Stage, tasks: string[]) {
|
|
|
|
if(loaderStageContainer)
|
|
|
|
loaderStageContainer.innerText = StageNames[state] + (tasks.length === 1 ? " (task: " + tasks[0] + ")" : " (tasks: " + tasks.join(",") + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
function setupAnimationFinished() {
|
|
|
|
verbose && console.log("Entering idle animation");
|
|
|
|
|
|
|
|
setupContainer.classList.remove("visible");
|
2020-10-04 18:47:19 +00:00
|
|
|
if(animationType === "halloween") {
|
|
|
|
loopInterval = setInterval(() => idleSteamAnimationLooped(), 1000);
|
|
|
|
idleHalloweenContainer.classList.add("visible");
|
|
|
|
} else {
|
|
|
|
idleNormalContainer.classList.add("visible");
|
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function idleSteamAnimationLooped() {
|
|
|
|
verbose && console.log("Idle animation looped. Should finalize: %o", finalizing);
|
2020-10-04 18:47:19 +00:00
|
|
|
if(!finalizing) {
|
2020-07-13 09:29:16 +00:00
|
|
|
return;
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
2020-10-04 18:47:19 +00:00
|
|
|
clearInterval(loopInterval);
|
|
|
|
loopInterval = 0;
|
2020-07-13 09:29:16 +00:00
|
|
|
overlay.classList.add("finishing");
|
|
|
|
}
|
|
|
|
|
|
|
|
function overlayAnimationFinished(event: AnimationEvent) {
|
|
|
|
/* the text animation is the last one */
|
2020-10-04 18:47:19 +00:00
|
|
|
if(event.animationName !== "swipe-out-text") {
|
2020-07-13 09:29:16 +00:00
|
|
|
return;
|
2020-10-04 18:47:19 +00:00
|
|
|
}
|
2020-07-13 09:29:16 +00:00
|
|
|
|
|
|
|
verbose && console.log("Animation finished");
|
|
|
|
overlay.remove();
|
|
|
|
}
|