mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-04 21:17:30 +00:00
* fix(skills): mount music-to-video motion primitives as sub-compositions Each primitive's root now only mounts scene.html, so the root is built from a sub-composition and the structure lint has nothing to flag. Renders match the originals (31 of 37 identical, the rest above 54 dB PSNR). Registry examples mark their caption layer with data-track-kind=captions. * fix(skills): keep primitive variables and page styles where the runtime reads them Composition variables move onto the sub-composition element, the dead #scene rule is dropped, and the frame-worker doc names where page styles live. * fix(skills): shorten a carried-over comment in the kinetic-letter-in scene
160 lines
4.5 KiB
HTML
Vendored
160 lines
4.5 KiB
HTML
Vendored
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=1920, height=1080" />
|
|
<title>Product Promo</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;800&display=block"
|
|
rel="stylesheet"
|
|
/>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
html,
|
|
body {
|
|
margin: 0;
|
|
width: 1920px;
|
|
height: 1080px;
|
|
overflow: hidden;
|
|
background: #0a0a0f;
|
|
font-family: "Inter", sans-serif;
|
|
}
|
|
.scene {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.caption-text-wrapper {
|
|
position: absolute;
|
|
bottom: 150px;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
justify-content: center;
|
|
pointer-events: none;
|
|
overflow: hidden;
|
|
padding: 10px 0;
|
|
}
|
|
.caption-line {
|
|
color: white;
|
|
font-size: 48px;
|
|
font-weight: 600;
|
|
letter-spacing: -0.02em;
|
|
text-align: center;
|
|
text-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
|
transform: translateY(100%);
|
|
opacity: 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div
|
|
id="root"
|
|
data-composition-id="main"
|
|
data-start="0"
|
|
data-duration="20"
|
|
data-width="1920"
|
|
data-height="1080"
|
|
>
|
|
<!-- Scene 1: Logo Intro -->
|
|
<div
|
|
id="scene-1"
|
|
class="scene"
|
|
data-composition-id="scene1-logo-intro"
|
|
data-composition-src="compositions/scene1-logo-intro.html"
|
|
data-start="0"
|
|
data-duration="1.5"
|
|
data-track-index="1"
|
|
data-width="1920"
|
|
data-height="1080"
|
|
></div>
|
|
|
|
<!-- Scene 2-4: Continuous Canvas -->
|
|
<div
|
|
id="scene-2-4"
|
|
class="scene"
|
|
data-composition-id="scene2-4-canvas"
|
|
data-composition-src="compositions/scene2-4-canvas.html"
|
|
data-start="1.5"
|
|
data-duration="12.5"
|
|
data-track-index="1"
|
|
data-width="1920"
|
|
data-height="1080"
|
|
></div>
|
|
|
|
<!-- Scene 5: Logo Outro -->
|
|
<div
|
|
id="scene-5"
|
|
class="scene"
|
|
data-composition-id="scene5-logo-outro"
|
|
data-composition-src="compositions/scene5-logo-outro.html"
|
|
data-start="14"
|
|
data-duration="6"
|
|
data-track-index="1"
|
|
data-width="1920"
|
|
data-height="1080"
|
|
></div>
|
|
|
|
<!-- Captions -->
|
|
<div
|
|
id="captions-comp"
|
|
data-track-kind="captions"
|
|
data-composition-id="captions"
|
|
data-start="1.5"
|
|
data-duration="12.5"
|
|
data-track-index="2"
|
|
data-width="1920"
|
|
data-height="1080"
|
|
>
|
|
<div class="caption-text-wrapper">
|
|
<div id="caption-text" class="caption-line">Starting with a blank canvas.</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
const tl = gsap.timeline({ paused: true });
|
|
const text = document.querySelector("#caption-text");
|
|
|
|
tl.to(text, { opacity: 1, y: 0, duration: 0.8, ease: "power3.out" }, 0);
|
|
tl.to(text, { opacity: 0, y: -20, duration: 0.3, ease: "power3.in" }, 3.2);
|
|
tl.set(text, { innerText: "Three cursors. One file. Zero meetings.", y: 40 }, 3.5);
|
|
tl.to(text, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, 3.5);
|
|
tl.to(text, { opacity: 0, y: -20, duration: 0.3, ease: "power3.in" }, 7.7);
|
|
tl.set(
|
|
text,
|
|
{ innerText: "Components in. Feedback resolved. No one waited.", y: 40 },
|
|
8.0,
|
|
);
|
|
tl.to(text, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, 8.0);
|
|
tl.to(text, { opacity: 0, y: -20, duration: 0.4, ease: "power3.in" }, 12.1);
|
|
|
|
window.__timelines = window.__timelines || {};
|
|
window.__timelines["captions"] = tl;
|
|
})();
|
|
</script>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
window.__timelines = window.__timelines || {};
|
|
const mainTl = gsap.timeline({ paused: true });
|
|
|
|
mainTl.set("#scene-2-4", { scale: 1, filter: "blur(0px)" }, 1.5);
|
|
mainTl.to(
|
|
"#scene-2-4",
|
|
{ duration: 0.25, scale: 0.94, filter: "blur(6px)", opacity: 0, ease: "power2.in" },
|
|
13.75,
|
|
);
|
|
|
|
window.__timelines["main"] = mainTl;
|
|
</script>
|
|
</body>
|
|
</html>
|