feat: Change loading animation

This commit is contained in:
overflowerror 2024-08-02 22:52:46 +02:00
parent be991b99fc
commit 90bd9ef5ca
6 changed files with 46 additions and 23 deletions

View file

@ -50,24 +50,18 @@ h1 {
text-align: center; text-align: center;
transform: translate(0%, -50%); transform: translate(0%, -50%);
opacity: 1; opacity: 1;
transition: opacity 0.5s; transition: opacity 0.2s;
} }
.middle .spinner { .loading .or {
opacity: 0; opacity: 0;
} }
.img-preload .spinner { .loading .spinner img {
opacity: 1;
}
.img-preload .or {
opacity: 0;
}
.middle .spinner img {
animation-name: spinner; animation-name: spinner;
animation-duration: 1s; animation-duration: 1s;
animation-iteration-count: infinite; animation-delay: 0.2s;
animation-iteration-count: 1;
animation-timing-function: cubic-bezier(0.68, -0.6, 0.32, 1.6); animation-timing-function: cubic-bezier(0.68, -0.6, 0.32, 1.6);
} }
@ -80,7 +74,6 @@ h1 {
} }
} }
.mob { .mob {
width: 40vw; width: 40vw;
height: 42vw; height: 42vw;

View file

@ -13,14 +13,9 @@ htmx.defineExtension('img-preload', {
return; return;
} }
const getSpinners = () => [...document.querySelectorAll(
event.target.getAttribute("data-preload-spinner")
?? ".img-preload"
)];
switch (name) { switch (name) {
case 'htmx:trigger': case 'htmx:trigger':
getSpinners().forEach(s => s.classList.add("img-preload")); [eval][0](event.target.getAttribute("data-loading-callback"));
break; break;
case 'htmx:beforeOnLoad': case 'htmx:beforeOnLoad':
event.detail.shouldSwap = false; event.detail.shouldSwap = false;
@ -42,7 +37,7 @@ htmx.defineExtension('img-preload', {
swapStyle: "outerHTML", swapStyle: "outerHTML",
transition: true, transition: true,
}); });
getSpinners().forEach(s => s.classList.remove("img-preload")) [eval][0](event.target.getAttribute("data-loaded-callback"));
}) })
.catch(error => { .catch(error => {
console.error('Error loading images:', error); console.error('Error loading images:', error);

View file

@ -1,2 +1,4 @@
import './htmx'; import './htmx';
import './img-preload.ext'; import './img-preload.ext';
import './spinner';

33
resources/js/spinner.js Normal file
View file

@ -0,0 +1,33 @@
var spinnerActive = false;
const triggerAnimation = () => {
setTimeout(() => {
document.getElementsByClassName("middle")[0].classList.add("loading");
}, 1);
}
const endAnimation = () => {
document.getElementsByClassName("middle")[0].classList.remove("loading");
}
window.startSpinner = () => {
if (spinnerActive) {
return
}
spinnerActive = true;
document.getElementsByClassName("middle")[0].classList.add("loading");
}
window.stopSpinner = () => {
spinnerActive = false;
}
window.addEventListener("load", () => {
document.querySelector(".middle .spinner img")
.addEventListener("animationend", () => {
endAnimation();
if (spinnerActive) {
triggerAnimation();
}
});
});

View file

@ -6,7 +6,7 @@
<div class="mob" onclick="htmx.trigger(document.forms['<?= $side ?>'], 'submit', {})" id="form-<?= $side ?>"> <div class="mob" onclick="htmx.trigger(document.forms['<?= $side ?>'], 'submit', {})" id="form-<?= $side ?>">
<form action="?<?= $side ?>" method="POST" name="<?= $side ?>" <form action="?<?= $side ?>" method="POST" name="<?= $side ?>"
data-hx-post="?<?= $side ?>&ajax" data-hx-target=".selection" data-hx-swap="outerHTML" data-hx-post="?<?= $side ?>&ajax" data-hx-target=".selection" data-hx-swap="outerHTML"
data-hx-ext="img-preload" data-preload-spinner=".middle"> data-hx-ext="img-preload" data-loading-callback="startSpinner()" data-loaded-callback="stopSpinner()">
<input type="hidden" name="csrfToken" value="<?= $csrfToken ?>"> <input type="hidden" name="csrfToken" value="<?= $csrfToken ?>">
<h2><?= $mob["name"]; ?></h2> <h2><?= $mob["name"]; ?></h2>
<img alt="<?= $mob["name"]; ?>" src="/images/mobs/<?= $mob["image"] ?? "_placeholder.png"; ?>"> <img alt="<?= $mob["name"]; ?>" src="/images/mobs/<?= $mob["image"] ?? "_placeholder.png"; ?>">

View file

@ -8,11 +8,11 @@
require_once __DIR__ . "/../fragments/mobSelection.php"; require_once __DIR__ . "/../fragments/mobSelection.php";
?> ?>
<div class="middle"> <div class="middle">
<div class="or">
OR
</div>
<div class="spinner"> <div class="spinner">
<img src="/images/gras.png" alt="spinner" /> <img src="/images/gras.png" alt="spinner" />
</div> </div>
<div class="or">
OR
</div>
</div> </div>
</div> </div>