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.
