Skip to content

Commit e6b197e

Browse files
Bikram GoleBikram Gole
authored andcommitted
Animate snapshot terminal lines
1 parent b260104 commit e6b197e

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

script.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,72 @@ function initHeroTypewriters() {
16091609
window.setTimeout(loopStatus, 360);
16101610
}
16111611

1612+
function initCliSnapshotTypewriter() {
1613+
if (page !== "home") return;
1614+
const snapshot = document.getElementById("cli-snapshot");
1615+
if (!snapshot) return;
1616+
const lines = Array.from(snapshot.querySelectorAll(".cli-block span"));
1617+
if (!lines.length) return;
1618+
1619+
const originalLines = lines.map((span) => span.textContent || "");
1620+
if (prefersReducedMotion) {
1621+
lines.forEach((span, index) => {
1622+
span.textContent = originalLines[index] || "";
1623+
});
1624+
return;
1625+
}
1626+
1627+
let hasStarted = false;
1628+
const startTyping = () => {
1629+
if (hasStarted) return;
1630+
hasStarted = true;
1631+
1632+
lines.forEach((span) => {
1633+
if (span.classList.contains("cli-gap")) {
1634+
span.textContent = "\u00A0";
1635+
} else {
1636+
span.textContent = "";
1637+
}
1638+
});
1639+
1640+
const typeLine = (index) => {
1641+
if (index >= lines.length) return;
1642+
const span = lines[index];
1643+
const text = originalLines[index] || "";
1644+
1645+
if (span.classList.contains("cli-gap")) {
1646+
span.textContent = "\u00A0";
1647+
window.setTimeout(() => typeLine(index + 1), 140);
1648+
return;
1649+
}
1650+
1651+
const speed = span.classList.contains("cli-prompt") ? 18 : 20;
1652+
typeTextTo(span, text, speed, "");
1653+
const duration = Math.max(text.length * speed + 120, 200);
1654+
window.setTimeout(() => typeLine(index + 1), duration);
1655+
};
1656+
1657+
window.setTimeout(() => typeLine(0), 160);
1658+
};
1659+
1660+
if ("IntersectionObserver" in window) {
1661+
const observer = new IntersectionObserver(
1662+
(entries) => {
1663+
entries.forEach((entry) => {
1664+
if (entry.isIntersecting) {
1665+
startTyping();
1666+
observer.disconnect();
1667+
}
1668+
});
1669+
},
1670+
{ threshold: 0.2 }
1671+
);
1672+
observer.observe(snapshot);
1673+
} else {
1674+
startTyping();
1675+
}
1676+
}
1677+
16121678
function initNamePronounce() {
16131679
if (!nameSpeakBtn) return;
16141680
if (!("speechSynthesis" in window) || typeof SpeechSynthesisUtterance === "undefined") {
@@ -2098,6 +2164,7 @@ initPenguinDateBadge();
20982164
initThemeSwitcher();
20992165
initNavThemeGuard();
21002166
initHeroTypewriters();
2167+
initCliSnapshotTypewriter();
21012168
initNamePronounce();
21022169
initBlackflagGunfire();
21032170
initRuntimeCompatibility();

0 commit comments

Comments
 (0)