From cc068d8245138f36f45c3999b78b8f9ecb209fc5 Mon Sep 17 00:00:00 2001 From: tobspr Date: Thu, 16 Jun 2022 13:47:11 +0200 Subject: [PATCH] Improve loading screen --- gulp/html.js | 84 +++++--------- gulp/preloader.css | 209 +++++++++++++++++++++++++++++++++++ src/js/core/game_state.js | 8 ++ src/js/core/state_manager.js | 9 +- src/js/states/preload.js | 22 ++-- 5 files changed, 260 insertions(+), 72 deletions(-) create mode 100644 gulp/preloader.css diff --git a/gulp/html.js b/gulp/html.js index ffdd1e78..833c5dec 100644 --- a/gulp/html.js +++ b/gulp/html.js @@ -92,59 +92,17 @@ function gulptasksHTML($, gulp, buildFolder) { }); } - const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`; - - const loadingCss = ` - @font-face { - font-family: 'GameFont'; - font-style: normal; - font-weight: normal; - font-display: swap; - src: url('${cachebust("res/fonts/GameFont.woff2")}') format('woff2'); - } - - #ll_fp { - font-family: GameFont; - font-size: 14px; - position: fixed; - z-index: -1; - top: 0; - left: 0; - opacity: 0.05; - } - - #ll_p { - display: flex; - position: fixed; - z-index: 99999; - top: 0; - left: 0; - right: 0; - bottom: 0; - justify-content: - center; - align-items: center; - } - - #ll_p > div { - position: absolute; - text-align: center; - bottom: 40px; - left: 20px; - right: 20px; - color: #393747; - font-family: 'GameFont', sans-serif; - font-size: 20px; - } - - #ll_p > span { - width: 60px; - height: 60px; - display: inline-flex; - background: center center / contain no-repeat; - ${loadingSvg}; - } - `; + let fontCss = ` + @font-face { + font-family: "GameFont"; + font-style: normal; + font-weight: normal; + font-display: swap; + src: url('${cachebust("res/fonts/GameFont.woff2")}') format("woff2"); + } + `; + let loadingCss = + fontCss + fs.readFileSync(path.join(__dirname, "preloader.css")).toString(); const style = document.createElement("style"); style.setAttribute("type", "text/css"); @@ -194,8 +152,24 @@ function gulptasksHTML($, gulp, buildFolder) { const bodyContent = `
_
- -
${hasLocalFiles ? "Loading" : "Downloading"} Game Files
+ +
+ +
${ + hasLocalFiles ? "Loading" : "Downloading" + } Game Files
+
+ +
+
+ Page does not load? Try the Steam Version! +
+
`; diff --git a/gulp/preloader.css b/gulp/preloader.css new file mode 100644 index 00000000..c625cf0d --- /dev/null +++ b/gulp/preloader.css @@ -0,0 +1,209 @@ +* { + margin: 0; + padding: 0; + touch-action: pan-x pan-y !important; + pointer-events: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); +} + +html { + position: fixed; + -ms-touch-action: pan-x, pan-y; + touch-action: pan-x, pan-y; + -ms-content-zooming: none; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: #dee1ea; +} + +body { + color: #555; + user-select: none; + -moz-user-select: none; + -ms-user-select: none; + background: inherit !important; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: break-word; + font-style: normal; + line-break: auto; + font-stretch: 100%; + text-rendering: optimizeLegibility; + text-decoration: none; + text-size-adjust: 100%; + letter-spacing: normal; + scrollbar-width: 6px; + -webkit-font-smoothing: antialiased; + -webkit-touch-callout: none; + /* prevent callout to copy image, etc when tap to hold */ + -webkit-text-size-adjust: none; + /* prevent webkit from resizing text to fit */ + scrollbar-face-color: #888; + scrollbar-track-color: rgba(255, 255, 255, 0.1); +} + +#ll_fp { + font-family: GameFont; + font-size: 14px; + position: fixed; + z-index: -1; + top: 0; + left: 0; + opacity: 0.05; +} + +#ll_p { + display: grid; + position: fixed; + z-index: 99999; + top: 0; + left: 0; + right: 0; + bottom: 0; + justify-content: center; + justify-items: center; + align-items: center; + background: #d5d8de; + grid-template-rows: 1fr 200px; + grid-gap: 40px; + padding: 20px; + font-size: 14px; +} + +#ll_p * { + line-height: 1em; +} + +#ll_loader { + display: flex; + flex-direction: column; + align-items: center; + justify-self: end; + justify-content: center; +} + +#ll_loader > .ll_text { + text-align: center; + color: #777a7f; + font-family: "GameFont", sans-serif; + font-size: 24px; + line-height: 1.2em; +} + +#ll_progressbar { + width: 80vw; + margin-top: 40px; + height: 30px; + overflow: hidden; + border-radius: 4px; + background: rgba(0, 0, 0, 0.03); + display: flex; + position: relative; + align-items: flex-start; +} + +@keyframes LL_LoadingAnimation { + 0% { + width: 0%; + background-color: #67aeed; + } + 19.99% { + width: 99.5%; + background-color: #67aeed; + } + 20% { + width: 0%; + background-color: #a1c074; + } + 49.99% { + width: 98%; + background-color: #a1c074; + } + 50% { + width: 0%; + background-color: #74a8c0; + } + 74.99% { + width: 98%; + background-color: #74a8c0; + } + 75% { + width: 0%; + background-color: #8f74c0; + } + 100% { + width: 98%; + background-color: #8f74c0; + } +} + +#ll_progressbar > span { + height: 100%; + border-radius: 7px; + width: 98%; + background: #fff; + display: inline-flex; + animation: LL_LoadingAnimation 40s ease-in-out infinite; + position: relative; + z-index: 10; +} + +#ll_progressbar > #ll_loadinglabel { + position: absolute; + z-index: 20; + top: 50%; + text-transform: uppercase; + border-radius: 7px; + left: 50%; + transform: translate(-50%, -50%); + font-size: 16px; + color: #33373f; +} + +@keyframes ShowStandaloneBannerAfterDelay { + 0% { + opacity: 0; + } + 95% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +#ll_standalone { + text-align: center; + color: #777a7f; + margin-top: 20px; + display: block; + font-size: 16px; + animation: ShowStandaloneBannerAfterDelay 20s linear; +} + +#ll_standalone a { + color: #39f; + margin-left: 5px; + font-weight: bold; +} + +#ll_logo { +} + +#ll_logo > img { + width: 40vw; + max-width: 700px; + min-width: 150px; +} + +#ll_loader > .ll_spinner { + width: 80px; + height: 80px; + display: inline-flex; + background: center center / contain no-repeat; + display: none; +} diff --git a/src/js/core/game_state.js b/src/js/core/game_state.js index fb08e28d..b67ff7ef 100644 --- a/src/js/core/game_state.js +++ b/src/js/core/game_state.js @@ -234,6 +234,14 @@ export class GameState { return MUSIC.menu; } + /** + * Should return whether to clear the whole body content before entering the state. + * @returns {boolean} + */ + getRemovePreviousContent() { + return true; + } + //////////////////// //// INTERNAL //// diff --git a/src/js/core/state_manager.js b/src/js/core/state_manager.js index e8a8ba94..77e934da 100644 --- a/src/js/core/state_manager.js +++ b/src/js/core/state_manager.js @@ -81,11 +81,16 @@ export class StateManager { this.currentState.internalRegisterCallback(this, this.app); // Clean up old elements - removeAllChildren(document.body); + if (this.currentState.getRemovePreviousContent()) { + removeAllChildren(document.body); + } document.body.className = "gameState " + (this.currentState.getHasFadeIn() ? "" : "arrived"); document.body.id = "state_" + key; - document.body.innerHTML = this.currentState.internalGetFullHtml(); + + if (this.currentState.getRemovePreviousContent()) { + document.body.innerHTML = this.currentState.internalGetFullHtml(); + } const dialogParent = document.createElement("div"); dialogParent.classList.add("modalDialogParent"); diff --git a/src/js/states/preload.js b/src/js/states/preload.js index f01d0a5e..def7393f 100644 --- a/src/js/states/preload.js +++ b/src/js/states/preload.js @@ -35,26 +35,17 @@ export class PreloadState extends GameState { return false; } - onEnter() { - this.htmlElement.classList.add("prefab_LoadingState"); - - const elementsToRemove = ["#loadingPreload", "#fontPreload"]; - for (let i = 0; i < elementsToRemove.length; ++i) { - const elem = document.querySelector(elementsToRemove[i]); - if (elem) { - elem.remove(); - } - } + getRemovePreviousContent() { + return false; + } + onEnter() { this.dialogs = new HUDModalDialogs(null, this.app); const dialogsElement = document.body.querySelector(".modalDialogParent"); this.dialogs.initializeToElement(dialogsElement); /** @type {HTMLElement} */ - this.statusText = this.htmlElement.querySelector(".loadingStatus > .desc"); - - /** @type {HTMLElement} */ - this.hintsText = this.htmlElement.querySelector(".prefab_GameHint"); + this.hintsText = this.htmlElement.querySelector("#preload_ll_text"); this.lastHintShown = -1000; this.nextHintDuration = 0; @@ -286,11 +277,12 @@ export class PreloadState extends GameState { */ setStatus(text) { logger.log("✅ " + text); + if (G_CHINA_VERSION || G_WEGAME_VERSION) { return Promise.resolve(); } this.currentStatus = text; - this.statusText.innerText = text; + // this.statusText.innerText = text; return Promise.resolve(); }