Try to make a nixos boot animation. (log scroll on screen.)
The repo link: https://github.com/ocfox/booti . This site has none imported js or css library.
First need make a animation let text display line by line. So I tried to set a delay for every line, when open page hide (don’t display) every paragraph in css.
p {
display: none; /* Initially hide all paragraphs */
margin: 1px 0 0 1px;
}
Then set a delay increase by degrees for every single line with js. Use EventListener
get every
paragraph element, and set 500ms * (current lines) delay make it display
none
-> block
.
So them will display right.
document.addEventListener("DOMContentLoaded", function() {
const paragraphs = document.querySelectorAll('p');
let delay = 500;
paragraphs.forEach((p, i) => {
setTimeout(() => {
p.style.display = 'block';
}, i * delay);
});
});
A basic Terminal like page css.
body {
background: #000; /* Black background */
padding-top: 10px;
color: white;
font-family: "Terminus", monospace;
font-size: 15px;
}
And every ‘OK’ should be green. so use script replace them class and css to change it color.
paragraphs.forEach(p => {
p.innerHTML = p.innerHTML.replace(/OK/g, '<span class="green">OK</span>');
});
.green {
color: green;
}
Now need a auto scroll, make sure it looks like real boot log. Just let it scroll to bottom when every line display.
paragraphs.forEach((p, i) => {
window.scrollTo(0, document.body.scrollHeight); // Scroll to the bottom of the page
setTimeout(() => {
p.style.display = 'block';
}, i * delay);
});
Last, replece 500ms to random delay. Now I need a blink cursor ‘_’. The blink is not animation, and the visibility switch, so it will like machanical switch.
<span class="blink">_</span>
.blink {
animation: blink 1s steps(1, end) infinite;
}
@keyframes blink {
50% {
visibility: hidden;
}
}
And a input box, I add a empty element as placeholder.
<span id="input-placeholder"></span><span class="blink">_</span>
input.dynamic-width {
background: transparent;
color: white;
border: none; /* Set border none to hide that highlit boader */
font-family: "Terminus", monospace;
font-size: 15px;
outline: none;
caret-color: transparent;
margin: 0;
padding: 0;
position: relative;
right: -10px; /* hacky way to move text to right, but not good way */
}
setTimeout(() => {
const input = document.createElement('input');
input.type = 'text';
input.classList.add('dynamic-width');
const placeholder = document.querySelector('#input-placeholder');
placeholder.replaceWith(input);
// Adjust input width dynamically based on content
input.addEventListener('input', () => {
input.style.width = ((input.value.length + 1) * 1) + 'ch';
});
input.focus();
function typeText(element, text, delay) {
let index = 0;
function addCharacter() {
if (index < text.length) {
element.value += text[index];
element.style.width = ((element.value.length + 1) * 1) + 'ch';
index++;
setTimeout(addCharacter, delay);
}
}
addCharacter();
}
input.focus();
typeText(input, 'hello', 200);
document.addEventListener('click', () => {
input.focus();
});
}, cumulativeDelay + 200);
This part a little long, but it simple. Today will poweroff soon. Tomorrow fill it.