mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 18:01:20 +08:00
256 lines
7.7 KiB
HTML
Vendored
256 lines
7.7 KiB
HTML
Vendored
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=1920, height=1080" />
|
||
<title>Apple Terminal Basic</title>
|
||
<style>
|
||
html,
|
||
body {
|
||
margin: 0;
|
||
padding: 0;
|
||
width: 1920px;
|
||
height: 1080px;
|
||
overflow: hidden;
|
||
background: #ececec;
|
||
font-family: "SF Mono", Menlo, Monaco, Consolas, "Courier New", monospace;
|
||
}
|
||
|
||
#scene {
|
||
width: 1920px;
|
||
height: 1080px;
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, #e8e8e8 0%, #d8d8d8 100%);
|
||
}
|
||
|
||
.terminal-window {
|
||
width: 1400px;
|
||
height: 700px;
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
box-shadow:
|
||
0 30px 80px rgba(0, 0, 0, 0.25),
|
||
0 10px 30px rgba(0, 0, 0, 0.15);
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.titlebar {
|
||
height: 38px;
|
||
background: #ececec;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 14px;
|
||
gap: 0;
|
||
flex-shrink: 0;
|
||
border-bottom: 1px solid #d0d0d0;
|
||
position: relative;
|
||
}
|
||
|
||
.traffic-lights {
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: center;
|
||
}
|
||
|
||
.traffic-lights span {
|
||
width: 13px;
|
||
height: 13px;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
}
|
||
|
||
.traffic-lights .close {
|
||
background: #ff5f57;
|
||
border: 1px solid #e0443e;
|
||
}
|
||
|
||
.traffic-lights .minimize {
|
||
background: #ffbd2e;
|
||
border: 1px solid #dfa123;
|
||
}
|
||
|
||
.traffic-lights .fullscreen {
|
||
background: #28c840;
|
||
border: 1px solid #1aab29;
|
||
}
|
||
|
||
.window-title {
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
font-size: 13px;
|
||
color: #333333;
|
||
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
|
||
font-weight: 500;
|
||
letter-spacing: -0.1px;
|
||
}
|
||
|
||
.terminal-canvas {
|
||
flex: 1;
|
||
background: #ffffff;
|
||
padding: 18px 20px;
|
||
overflow: hidden;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
color: #000000;
|
||
}
|
||
|
||
.output-lines {
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.output-line {
|
||
display: block;
|
||
white-space: pre;
|
||
opacity: 0;
|
||
color: #000000;
|
||
}
|
||
|
||
.output-line.bold {
|
||
font-weight: bold;
|
||
color: #000000;
|
||
}
|
||
|
||
.input-line {
|
||
display: flex;
|
||
align-items: center;
|
||
white-space: pre;
|
||
}
|
||
|
||
.prompt {
|
||
color: #000000;
|
||
font-weight: bold;
|
||
user-select: none;
|
||
}
|
||
|
||
.typed-command {
|
||
color: #000000;
|
||
}
|
||
|
||
.cursor-block {
|
||
display: inline-block;
|
||
width: 9px;
|
||
height: 16px;
|
||
background: #000000;
|
||
vertical-align: text-bottom;
|
||
margin-left: 1px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div
|
||
id="scene"
|
||
data-composition-id="code-snippet-apple-terminal-basic"
|
||
data-start="0"
|
||
data-width="1920"
|
||
data-height="1080"
|
||
>
|
||
<div class="terminal-window">
|
||
<div class="titlebar">
|
||
<div class="traffic-lights">
|
||
<span class="close"></span>
|
||
<span class="minimize"></span>
|
||
<span class="fullscreen"></span>
|
||
</div>
|
||
<span class="window-title">bash — 80×24</span>
|
||
</div>
|
||
<div class="terminal-canvas">
|
||
<div class="output-lines">
|
||
<span class="output-line">Last login: Mon Jun 2 09:14:22 on ttys001</span>
|
||
<span class="output-line">total 48</span>
|
||
<span class="output-line bold">drwxr-xr-x 8 user staff 256 Jun 2 09:10 .</span>
|
||
<span class="output-line">drwxr-xr-x 42 user staff 1344 Jun 1 18:22 ..</span>
|
||
<span class="output-line">-rw-r--r-- 1 user staff 872 May 30 14:05 README.md</span>
|
||
<span class="output-line bold">drwxr-xr-x 5 user staff 160 Jun 2 09:10 dist</span>
|
||
<span class="output-line bold"
|
||
>drwxr-xr-x 12 user staff 384 Jun 2 09:10 node_modules</span
|
||
>
|
||
<span class="output-line">-rw-r--r-- 1 user staff 1204 Jun 2 09:08 package.json</span>
|
||
<span class="output-line bold">drwxr-xr-x 6 user staff 192 Jun 2 09:10 src</span>
|
||
<span class="output-line">-rw-r--r-- 1 user staff 348 May 29 11:42 tsconfig.json</span>
|
||
</div>
|
||
<div class="input-line">
|
||
<span class="prompt">user@Mac ~ % </span><span class="typed-command"></span
|
||
><span class="cursor-block"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/animejs@4.5.0/dist/bundles/anime.umd.min.js"></script>
|
||
<script>
|
||
const command = "ls -la";
|
||
const typedEl = document.querySelector(".typed-command");
|
||
const cursorEl = document.querySelector(".cursor-block");
|
||
const inputLine = document.querySelector(".input-line");
|
||
const outputLines = [...document.querySelectorAll(".output-line")];
|
||
const finalPrompt = document.createElement("div");
|
||
finalPrompt.className = "input-line";
|
||
finalPrompt.innerHTML =
|
||
'<span class="prompt">user@Mac ~ % </span><span class="typed-command"></span><span class="cursor-block" id="final-cursor"></span>';
|
||
inputLine.parentNode.appendChild(finalPrompt);
|
||
const finalCursorEl = document.getElementById("final-cursor");
|
||
const charDuration = 1.5 / command.length;
|
||
const hideCursorTimeMs = 2200;
|
||
const clearCommandTimeMs = 2500;
|
||
const promptTimeMs = 4000;
|
||
const finalCursorStopMs = 6600;
|
||
const blinkTimes = [4.2, 4.6, 5.0, 5.4, 5.8, 6.2];
|
||
|
||
finalPrompt.style.display = "none";
|
||
|
||
const typedChars = command.split("").map((char) => {
|
||
const span = document.createElement("span");
|
||
span.textContent = char;
|
||
span.style.display = "none";
|
||
span.style.opacity = "0";
|
||
typedEl.appendChild(span);
|
||
return span;
|
||
});
|
||
|
||
function outputRevealTimeMs(index) {
|
||
return (index === 0 ? 2.3 : 2.8 + index * 0.08) * 1000;
|
||
}
|
||
|
||
const tl = anime.createTimeline({ autoplay: false });
|
||
const durationAnchor = { t: 0 };
|
||
tl.add(durationAnchor, { t: 1, duration: finalCursorStopMs, ease: "linear" }, 0);
|
||
|
||
tl.add(typedChars, { display: "none", opacity: 0, duration: 0 }, 0);
|
||
typedChars.forEach((span, i) => {
|
||
tl.add(
|
||
span,
|
||
{ display: "inline", opacity: 1, duration: 0 },
|
||
(0.5 + i * charDuration) * 1000,
|
||
);
|
||
});
|
||
tl.add(typedChars, { display: "none", opacity: 0, duration: 0 }, clearCommandTimeMs);
|
||
|
||
tl.add(cursorEl, { opacity: 1, duration: 0 }, 0);
|
||
tl.add(cursorEl, { opacity: 0, duration: 0 }, hideCursorTimeMs);
|
||
|
||
tl.add(inputLine, { display: "flex", duration: 0 }, 0);
|
||
tl.add(inputLine, { display: "none", duration: 0 }, promptTimeMs);
|
||
tl.add(finalPrompt, { display: "none", duration: 0 }, 0);
|
||
tl.add(finalPrompt, { display: "flex", duration: 0 }, promptTimeMs);
|
||
|
||
tl.add(finalCursorEl, { opacity: 1, duration: 0 }, 0);
|
||
blinkTimes.forEach((t, i) => {
|
||
tl.add(finalCursorEl, { opacity: i % 2 === 0 ? 0 : 1, duration: 0 }, t * 1000);
|
||
});
|
||
tl.add(finalCursorEl, { opacity: 1, duration: 0 }, finalCursorStopMs);
|
||
|
||
tl.add(outputLines, { opacity: 0, duration: 0 }, 0);
|
||
outputLines.forEach((line, i) => {
|
||
tl.add(line, { opacity: 1, duration: 0 }, outputRevealTimeMs(i));
|
||
});
|
||
|
||
hyperframesAnime.register("code-snippet-apple-terminal-basic", tl);
|
||
</script>
|
||
</body>
|
||
</html>
|