Compare commits

...

7 Commits

4 changed files with 68 additions and 50 deletions

View File

@ -20,6 +20,10 @@
"text": "C", "text": "C",
"author": "Dennis Ritchie" "author": "Dennis Ritchie"
}, },
{
"text": "UNIX",
"author": "Dennis Ritchie"
},
{ {
"text": "PICO", "text": "PICO",
"author": "Raspberry Pi" "author": "Raspberry Pi"
@ -40,9 +44,21 @@
"text": "GNU/LINUX", "text": "GNU/LINUX",
"author": "Linus Torvalds" "author": "Linus Torvalds"
}, },
{
"text": "GIT",
"author": "Linus Torvalds"
},
{ {
"text": "DEBIAN", "text": "DEBIAN",
"author": "Ian Murdock" "author": "Ian Murdock"
},
{
"text": "THE LEGEND OF ZELDA",
"author": "Nintendo"
},
{
"text": "SUPER MARIO BROS",
"author": "Nintendo"
} }
] ]
} }

View File

@ -1,96 +1,91 @@
function waitForAnimationEnd(elem, animationName) function waitForAnimationEnd(elem, animation_name)
{ {
return new Promise(resolve => { return new Promise(resolve => {
function handleAnimationEnd(evt) elem.onanimationend = (event) => {
{ if(event.animationName === animation_name)
if (evt.animationName === animationName)
{ {
elem.onanimationend = null; elem.onanimationend = null;
resolve(); resolve();
} }
} };
elem.onanimationend = handleAnimationEnd;
}); });
} }
let sound = new Audio("../assets/game-boy-advance-startup-sound.mp3"); let sound = new Audio("../assets/game-boy-advance-startup-sound.mp3");
sound.load();
async function sessionStartupAnimation() async function sessionStartupAnimation()
{ {
// Page setup // Page setup
let all_default_elements = document.body.querySelectorAll("*"); let default_elements = document.body.querySelectorAll("*");
all_default_elements.forEach((elem) => elem.style.opacity = 0); default_elements.forEach((elem) => elem.style.opacity = 0);
// Get quotes possibilities
// Not the most optimised way, but it's working
let xmlhttp = new XMLHttpRequest(); let xmlhttp = new XMLHttpRequest();
// Not the most optimised way, but it's working
xmlhttp.open("GET", "assets/startup_quotes.json", false); xmlhttp.open("GET", "assets/startup_quotes.json", false);
xmlhttp.send(); xmlhttp.send();
if(xmlhttp.status != 200) if(xmlhttp.status != 200)
{ {
throw WebTransportError("The file 'assets/startup_quots.json' is not available"); throw new WebTransportError({
message: "The file 'assets/startup_quotes.json' is not available",
streamErrorCode: xmlhttp.status
});
} }
let quotes = JSON.parse(xmlhttp.responseText)["quotes"]; let quotes = JSON.parse(xmlhttp.responseText)["quotes"];
let quote = quotes[Math.floor(Math.random() * quotes.length)]; let quote = quotes[Math.floor(Math.random() * quotes.length)];
// First the author // Add quote
let author_elem = document.createElement("h2");
author_elem.className = "startup-animation-author";
author_elem.innerHTML = quote.author + "<sup>®</sup>";
document.body.appendChild(author_elem);
await waitForAnimationEnd(author_elem, "opacity-fade-in")
// Then the text and sound
let text_elem = document.createElement("h1"); let text_elem = document.createElement("h1");
text_elem.className = "startup-animation-text"; text_elem.className = "startup-animation-text";
text_elem.style.setProperty("--delay", String(200 / quote.text.length));
let time_between_chars = 200 / quote.text.length; // ms
for(let i = 0; i < quote.text.length; i++) for(let i = 0; i < quote.text.length; i++)
{ {
let char_elem = document.createElement("div"); let char_elem = document.createElement("div");
char_elem.className = "startup-animation-char" char_elem.className = "startup-animation-char"
char_elem.style.animation = char_elem.style.setProperty("--char-nb", String(i));
"char-animation 3s ease-in-out " + String(i * time_between_chars) +
"ms, opacity-fade-in 1s " + String(i * time_between_chars) + "ms"; char_elem.onanimationstart = (event) => {
char_elem.onanimationstart = null;
event.target.style.opacity = 1;
};
if(quote.text[i] == " ") if(quote.text[i] == " ")
char_elem.innerHTML = "<pre>" + quote.text[i] + "</pre>"; char_elem.innerHTML = "&nbsp;";
else else
char_elem.textContent = quote.text[i]; char_elem.textContent = quote.text[i];
console.log(char_elem.onanimationend);
text_elem.appendChild(char_elem); text_elem.appendChild(char_elem);
} }
let author_elem = document.createElement("h2");
author_elem.className = "startup-animation-author";
author_elem.innerHTML = quote.author + "<sup>®</sup>";
author_elem.onanimationend = () => {
author_elem.onanimationend = null;
sound.play();
};
document.body.appendChild(text_elem); document.body.appendChild(text_elem);
document.body.appendChild(author_elem);
sound.play();
await waitForAnimationEnd(text_elem.firstChild, "opacity-fade-in");
text_elem.childNodes.forEach((char_elem) => char_elem.style.opacity = 1);
await waitForAnimationEnd(text_elem.lastChild, "char-animation");
// Fade out for both
text_elem.style.animation = "opacity-fade-out 1s ease-in";
text_elem.style.opacity = 0;
author_elem.style.animation = "opacity-fade-out 1s ease-in";
author_elem.style.opacity = 0;
await waitForAnimationEnd(text_elem, "opacity-fade-out"); await waitForAnimationEnd(text_elem, "opacity-fade-out");
// Remove them and fade in for page content // Remove quote and fade in page content
document.body.removeChild(author_elem); document.body.removeChild(author_elem);
document.body.removeChild(text_elem); document.body.removeChild(text_elem);
all_default_elements.forEach((elem) => elem.style.animation = "opacity-fade-in 0.5s"); default_elements.forEach((default_elem) => {
all_default_elements.forEach((elem) => elem.style.opacity = 1); default_elem.style.animation = "opacity-fade-in 0.5s ease-in";
default_elem.onanimationend = () => {
default_elem.onanimationend = null;
default_elem.removeAttribute("style");
}
});
window.onkeydown = null; window.onkeydown = null;
} }
@ -107,8 +102,8 @@ function interruptStartingAnimation()
let text_elem = document.body.querySelectorAll(".startup-animation-char"); let text_elem = document.body.querySelectorAll(".startup-animation-char");
text_elem.forEach((char_elem) => char_elem.getAnimations().forEach((animation) => { text_elem.forEach((char_elem) => char_elem.getAnimations().forEach((animation) => {
// No need to skip fade-out because it is handled by startup-animation-text // No need to skip fade-out because it is handled by startup-animation-text
if(animation.currentTime < 2800) if(animation.currentTime < 3600)
animation.currentTime = 2800; animation.currentTime = 3600;
})); }));
if(sound.currentTime < 2.75) if(sound.currentTime < 2.75)
@ -123,7 +118,7 @@ window.onkeydown = () => {
// Only start animation once per session // Only start animation once per session
window.onload = () => { window.onload = () => {
document.body.style.opacity = 1; document.body.removeAttribute("style");
if(!sessionStorage.getItem("hasExecutedSessionStartupAnimation")) if(!sessionStorage.getItem("hasExecutedSessionStartupAnimation"))
{ {

View File

@ -1,4 +1,7 @@
body { body {
margin: 0;
height: 100%;
width: 100%;
background-color: #151416; background-color: #151416;
color: white; color: white;
} }

View File

@ -68,7 +68,7 @@
width: 100%; width: 100%;
top: 23%; top: 23%;
text-align: center; text-align: center;
align-items: end; align-items: flex-end;
justify-content: center; justify-content: center;
display: flex; display: flex;
} }
@ -80,6 +80,9 @@
.startup-animation-char { .startup-animation-char {
position: relative; position: relative;
opacity: 0; opacity: 0;
animation: char-animation 2.9s ease-in-out calc(var(--delay) * var(--char-nb) * 1ms + 1s),
opacity-fade-in 1s calc(var(--delay) * var(--char-nb) * 1ms + 1s),
opacity-fade-out 1s ease-in 4s;
} }
.startup-animation-author { .startup-animation-author {
@ -92,5 +95,6 @@
bottom: 20%; bottom: 20%;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
animation: opacity-fade-in 1s ease-in; animation: opacity-fade-in 1s ease-in,
opacity-fade-out 1s ease-in 4s;
} }