mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
184 lines
5.1 KiB
HTML
Vendored
184 lines
5.1 KiB
HTML
Vendored
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=1920, height=1080" />
|
||
<title>Captions – Cinematic</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link
|
||
href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,300;0,400;1,300&display=block"
|
||
rel="stylesheet"
|
||
/>
|
||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
html,
|
||
body {
|
||
margin: 0;
|
||
width: 1920px;
|
||
height: 1080px;
|
||
overflow: hidden;
|
||
background: #000;
|
||
}
|
||
|
||
#captions-cinematic {
|
||
position: relative;
|
||
width: 1920px;
|
||
height: 1080px;
|
||
overflow: hidden;
|
||
background: linear-gradient(180deg, #0a0908 0%, #0f0d0a 50%, #0a0908 100%);
|
||
}
|
||
|
||
/* Warm vignette */
|
||
#captions-cinematic::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(ellipse at center, transparent 50%, rgba(0, 0, 0, 0.4) 100%);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.caption-wrapper {
|
||
position: absolute;
|
||
bottom: 140px;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 16px;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
will-change: opacity;
|
||
}
|
||
|
||
.caption-line {
|
||
position: relative;
|
||
width: 120px;
|
||
height: 1px;
|
||
background: rgba(245, 240, 232, 0.4);
|
||
transform: scaleX(0);
|
||
will-change: transform;
|
||
}
|
||
|
||
.caption-text {
|
||
font-family: "Inter", system-ui, sans-serif;
|
||
font-weight: 300;
|
||
font-style: italic;
|
||
font-size: 48px;
|
||
line-height: 1.4;
|
||
color: #f5f0e8;
|
||
letter-spacing: 4px;
|
||
text-align: center;
|
||
opacity: 0;
|
||
will-change: opacity, letter-spacing;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.driver {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 1px;
|
||
height: 1px;
|
||
opacity: 0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div
|
||
id="captions-cinematic"
|
||
data-composition-id="captions-cinematic"
|
||
data-width="1920"
|
||
data-height="1080"
|
||
data-start="0"
|
||
data-duration="13"
|
||
data-root="true"
|
||
>
|
||
<div class="driver" data-track-index="0"></div>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
var GROUPS = [
|
||
{ text: "Write HTML", start: 0.3, end: 1.8 },
|
||
{ text: "render video", start: 2.0, end: 3.5 },
|
||
{ text: "No timeline editors", start: 3.8, end: 5.5 },
|
||
{ text: "no After Effects", start: 5.7, end: 7.2 },
|
||
{ text: "Ship 10x faster", start: 7.5, end: 9.5 },
|
||
{ text: "with HyperFrames", start: 9.8, end: 12.0 },
|
||
];
|
||
|
||
var root = document.getElementById("captions-cinematic");
|
||
|
||
// Build caption group elements: line + text
|
||
GROUPS.forEach(function (group, gi) {
|
||
var wrapper = document.createElement("div");
|
||
wrapper.className = "caption-wrapper";
|
||
wrapper.id = "cg-wrap-" + gi;
|
||
|
||
var line = document.createElement("div");
|
||
line.className = "caption-line";
|
||
line.id = "cg-line-" + gi;
|
||
|
||
var text = document.createElement("div");
|
||
text.className = "caption-text";
|
||
text.id = "cg-" + gi;
|
||
text.textContent = group.text;
|
||
|
||
wrapper.appendChild(line);
|
||
wrapper.appendChild(text);
|
||
root.appendChild(wrapper);
|
||
});
|
||
|
||
// Build timeline
|
||
var tl = gsap.timeline({ paused: true });
|
||
|
||
GROUPS.forEach(function (group, gi) {
|
||
var wrapEl = "#cg-wrap-" + gi;
|
||
var lineEl = "#cg-line-" + gi;
|
||
var textEl = "#cg-" + gi;
|
||
|
||
// Show wrapper
|
||
tl.set(wrapEl, { opacity: 1, visibility: "visible" }, group.start);
|
||
|
||
// Line extends from center
|
||
tl.fromTo(
|
||
lineEl,
|
||
{ scaleX: 0 },
|
||
{ scaleX: 1, duration: 0.4, ease: "power2.out", transformOrigin: "center" },
|
||
group.start,
|
||
);
|
||
|
||
// Text fades in with letter-spacing settling
|
||
tl.fromTo(
|
||
textEl,
|
||
{ opacity: 0, letterSpacing: "8px" },
|
||
{ opacity: 1, letterSpacing: "4px", duration: 0.6, ease: "power1.out" },
|
||
group.start + 0.1,
|
||
);
|
||
|
||
// Text fades out slowly
|
||
tl.to(textEl, { opacity: 0, duration: 0.4, ease: "power1.in" }, group.end - 0.4);
|
||
|
||
// Line contracts
|
||
tl.to(lineEl, { scaleX: 0, duration: 0.3, ease: "power2.in" }, group.end - 0.3);
|
||
|
||
// Hard kill
|
||
tl.set(wrapEl, { opacity: 0, visibility: "hidden" }, group.end);
|
||
tl.set(textEl, { opacity: 0 }, group.end);
|
||
tl.set(lineEl, { scaleX: 0 }, group.end);
|
||
});
|
||
|
||
window.__timelines = window.__timelines || [];
|
||
window.__timelines.push(tl);
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|