mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-02 12:08:50 +00:00
feat(registry): bring back the video-primitive moves (#3169)
Restores the 208 catalog items reverted after their previews 404'd in production, this time on the payload mechanism rather than the .html files that caused the outage. The generator no longer writes a preview document to docs/public. That writer, and the machinery under it, existed only to produce files the docs host discards, so it is gone rather than bypassed. Items now embed the composition itself via a payload, which is what the previous change already does for the items that were already in the catalog. The variables explorer is parked, not restored: it drove its preview through the same unpublished .html path, so it would have shown an empty frame. Items that declare variables get the live player plus the static variables table, and reconnecting the explorer to payloads is a follow-up.
This commit is contained in:
@@ -3,26 +3,279 @@ title: "Code Snippet - Apple Terminal Clear Light"
|
||||
description: "Apple Terminal Clear Light profile: semi-transparent light background, per-character typing animation of a shell session."
|
||||
---
|
||||
|
||||
import { InstallCommand } from "/snippets/install-command.jsx";
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video rounded-xl border-0 bg-zinc-100 dark:bg-zinc-800"
|
||||
title="code-snippet-apple-terminal-clear-light preview"
|
||||
loading="lazy"
|
||||
srcDoc={`<!doctype html><html><head><meta charset="utf-8"><style>html,body{margin:0;height:100%;overflow:hidden;background:transparent}hyperframes-player{display:block;width:100%;height:100%}</style><script src="https://cdn.jsdelivr.net/npm/@hyperframes/player@0.7/dist/hyperframes-player.global.js"><\/script></head><body><script>fetch("/public/catalog/blocks/code-snippet-apple-terminal-clear-light.json").then(function(r){return r.json()}).then(function(d){var p=document.createElement("hyperframes-player");p.setAttribute("srcdoc",d.html);p.setAttribute("controls","");p.setAttribute("autoplay","");p.setAttribute("loop","");p.setAttribute("muted","");document.body.appendChild(p)});<\/script></body></html>`}
|
||||
srcDoc={`<!doctype html><html><head><meta charset="utf-8"><style>html,body{margin:0;height:100%;overflow:hidden;background:transparent}hyperframes-player{display:block;width:100%;height:100%}</style><script src="https://cdn.jsdelivr.net/npm/@hyperframes/player@0.7/dist/hyperframes-player.global.js"><\/script></head><body><script>fetch("/public/catalog/blocks/code-snippet-apple-terminal-clear-light.json").then(function(r){return r.json()}).then(function(d){var p=document.createElement("hyperframes-player");p.setAttribute("srcdoc",d.html);p.setAttribute("controls","");p.setAttribute("autoplay","");p.setAttribute("loop","");p.setAttribute("muted","");p.setAttribute("poster","https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/code-snippet-apple-terminal-clear-light.png");document.body.appendChild(p)});<\/script></body></html>`}
|
||||
/>
|
||||
|
||||
## Install
|
||||
|
||||
```bash Terminal
|
||||
npx hyperframes add code-snippet-apple-terminal-clear-light
|
||||
```
|
||||
<InstallCommand command="npx hyperframes add code-snippet-apple-terminal-clear-light" />
|
||||
|
||||
That writes one file: `compositions/code-snippet-apple-terminal-clear-light.html`.
|
||||
|
||||
## Add it to your video
|
||||
## Source
|
||||
|
||||
It runs for 12 seconds at 1920×1080. Paste this into your composition:
|
||||
<Accordion title={`code-snippet-apple-terminal-clear-light.html`}>
|
||||
|
||||
```html index.html
|
||||
```html
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<title>Apple Terminal Clear Light</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
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, #f5f5f5 0%, #e8e8e8 100%);
|
||||
}
|
||||
|
||||
.terminal-window {
|
||||
width: 1400px;
|
||||
height: 700px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 30px 80px rgba(0, 0, 0, 0.18),
|
||||
0 10px 30px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.titlebar {
|
||||
height: 38px;
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
position: relative;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.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: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px 20px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #000000;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.output-lines {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.output-line {
|
||||
display: block;
|
||||
white-space: pre;
|
||||
opacity: 0;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.output-line.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.output-line.muted {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.input-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
color: #888888;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.typed-command {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.cursor-block {
|
||||
display: inline-block;
|
||||
width: 9px;
|
||||
height: 16px;
|
||||
background: #888888;
|
||||
vertical-align: text-bottom;
|
||||
margin-left: 1px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
id="scene"
|
||||
data-composition-id="code-snippet-apple-terminal-clear-light"
|
||||
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 muted">Last login: Mon Jun 2 09:14:22 on ttys003</span>
|
||||
<span class="output-line bold">git log --oneline -8</span>
|
||||
<span class="output-line">a3f2c19 fix: correct off-by-one in pagination</span>
|
||||
<span class="output-line">b7e8d04 feat: add dark mode toggle</span>
|
||||
<span class="output-line">c1a9f55 refactor: extract auth helpers</span>
|
||||
<span class="output-line">d4e2b31 test: add unit tests for parser</span>
|
||||
<span class="output-line">e6c8a72 docs: update API reference</span>
|
||||
<span class="output-line">f9b1d44 chore: bump dependencies</span>
|
||||
<span class="output-line">2a7e890 feat: implement search endpoint</span>
|
||||
<span class="output-line">3c5f012 init: project bootstrap</span>
|
||||
</div>
|
||||
<div class="input-line">
|
||||
<span class="prompt">user@Mac myproject % </span><span class="typed-command"></span
|
||||
><span class="cursor-block"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<script>
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
const command = "git log --oneline -8";
|
||||
const typedEl = document.querySelector(".typed-command");
|
||||
const cursorEl = document.querySelector(".cursor-block");
|
||||
const outputLines = document.querySelectorAll(".output-line");
|
||||
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
|
||||
tl.set(typedEl, { text: "" }, 0);
|
||||
|
||||
const charDuration = 1.5 / command.length;
|
||||
command.split("").forEach((char, i) => {
|
||||
tl.add(
|
||||
() => {
|
||||
typedEl.textContent = command.slice(0, i + 1);
|
||||
},
|
||||
0.5 + i * charDuration,
|
||||
);
|
||||
});
|
||||
|
||||
tl.set(cursorEl, { opacity: 0 }, 2.2);
|
||||
tl.set(outputLines[0], { opacity: 1 }, 2.3);
|
||||
|
||||
tl.add(() => {
|
||||
typedEl.textContent = "";
|
||||
}, 2.5);
|
||||
|
||||
outputLines.forEach((line, i) => {
|
||||
if (i === 0) return;
|
||||
tl.set(line, { opacity: 1 }, 2.8 + i * 0.09);
|
||||
});
|
||||
|
||||
tl.add(() => {
|
||||
const inputLine = document.querySelector(".input-line");
|
||||
const newPrompt = document.createElement("div");
|
||||
newPrompt.className = "input-line";
|
||||
newPrompt.innerHTML =
|
||||
'<span class="prompt">user@Mac myproject % </span><span class="typed-command"></span><span class="cursor-block" id="final-cursor"></span>';
|
||||
inputLine.style.display = "none";
|
||||
inputLine.parentNode.appendChild(newPrompt);
|
||||
}, 4.0);
|
||||
|
||||
const blinkTimes = [4.2, 4.6, 5.0, 5.4, 5.8, 6.2];
|
||||
blinkTimes.forEach((t, i) => {
|
||||
tl.add(() => {
|
||||
const fc = document.getElementById("final-cursor");
|
||||
if (fc) fc.style.opacity = i % 2 === 0 ? "0" : "1";
|
||||
}, t);
|
||||
});
|
||||
tl.add(() => {
|
||||
const fc = document.getElementById("final-cursor");
|
||||
if (fc) fc.style.opacity = "1";
|
||||
}, 6.6);
|
||||
|
||||
window.__timelines["code-snippet-apple-terminal-clear-light"] = tl;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Usage
|
||||
|
||||
After installing, add the block to your host composition:
|
||||
|
||||
```html
|
||||
<div
|
||||
data-composition-id="code-snippet-apple-terminal-clear-light"
|
||||
data-composition-src="compositions/code-snippet-apple-terminal-clear-light.html"
|
||||
@@ -34,8 +287,14 @@ It runs for 12 seconds at 1920×1080. Paste this into your composition:
|
||||
></div>
|
||||
```
|
||||
|
||||
Move it in time with `data-start`. Put it on a different timeline row with
|
||||
`data-track-index`. See [data attributes](/concepts/data-attributes) for the rest.
|
||||
## Features
|
||||
|
||||
- Faithful recreation of macOS Terminal.app Clear Light profile — semi-transparent white background with black text
|
||||
- macOS window chrome with traffic light buttons and centered title bar
|
||||
- Per-character GSAP typing animation — command types out character by character
|
||||
- Output lines reveal sequentially after command executes
|
||||
- Cursor blinks three times at the end then holds steady
|
||||
- Self-contained HTML — no external assets, only GSAP CDN
|
||||
|
||||
{/* hf:generated-footer */}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user