mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 16:42:27 +00:00
This reverts commit 3b53bfd2f7.
This commit is contained in:
@@ -1,174 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<title>Zoom Through Transition - Demo</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#demo {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: #f7f7f8;
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
}
|
||||
.demo-frame {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 52px;
|
||||
/* ponytail: scale non-animated wrapper to fill ~65% of 1920×1080 */
|
||||
transform: scale(1.7);
|
||||
}
|
||||
.hf-remocn-zoom-through-transition {
|
||||
--hf-accent: var(--accent, rgba(255, 255, 255, 0.28));
|
||||
--hf-l1: rgba(255, 255, 255, 0.72);
|
||||
--hf-l3: rgba(255, 255, 255, 0.18);
|
||||
--hf-l4: rgba(255, 255, 255, 0.08);
|
||||
--hf-hair: rgba(255, 255, 255, 0.14);
|
||||
--hf-ink: #111827;
|
||||
--hf-muted: #6b7280;
|
||||
--hf-surface: #ffffff;
|
||||
color: var(--hf-ink);
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
}
|
||||
.hf-remocn-zoom-through-transition {
|
||||
position: relative;
|
||||
width: 760px;
|
||||
height: 428px;
|
||||
overflow: hidden;
|
||||
border-radius: 30px;
|
||||
background: #111827;
|
||||
box-shadow: 0 28px 80px rgba(15, 23, 42, 0.2);
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .scene {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-weight: 900;
|
||||
font-size: 58px;
|
||||
letter-spacing: -0.05em;
|
||||
color: #fff;
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .from {
|
||||
background:
|
||||
repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 4px),
|
||||
var(--hf-l4);
|
||||
transform: translate(var(--hf-from-x, 0px), var(--hf-from-y, 0px))
|
||||
scale(var(--hf-from-scale, 1));
|
||||
filter: blur(var(--hf-from-blur, 0px));
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .to {
|
||||
background:
|
||||
repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 4px),
|
||||
var(--hf-l3);
|
||||
box-shadow: inset 0 0 0 2px var(--hf-accent);
|
||||
transform: translate(var(--hf-to-x, 0px), var(--hf-to-y, 0px)) scale(var(--hf-to-scale, 1));
|
||||
clip-path: inset(
|
||||
var(--hf-clip-top, 0%) var(--hf-clip-right, 100%) var(--hf-clip-bottom, 0%)
|
||||
var(--hf-clip-left, 0%)
|
||||
);
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .fx {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.75), transparent);
|
||||
mix-blend-mode: screen;
|
||||
transform: translateX(var(--hf-fx-x, -110%));
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .rgb {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: var(--hf-rgb-opacity, 0);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(239, 68, 68, 0.35),
|
||||
transparent,
|
||||
rgba(34, 211, 238, 0.35)
|
||||
);
|
||||
transform: translateX(var(--hf-rgb-x, 0px));
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
id="demo"
|
||||
data-composition-id="zoom-through-transition-demo"
|
||||
data-start="0"
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
data-duration="5"
|
||||
>
|
||||
<div class="demo-frame">
|
||||
<div class="hf-remocn-zoom-through-transition">
|
||||
<div class="scene from">Before</div>
|
||||
<div class="scene to">Zoom Through Transition</div>
|
||||
<div class="fx"></div>
|
||||
<div class="rgb"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
const startTime = 0.5;
|
||||
tl.fromTo(
|
||||
".hf-remocn-zoom-through-transition .to",
|
||||
{ "--hf-clip-right": "100%", "--hf-to-x": "60px", "--hf-to-scale": 1.04 },
|
||||
{
|
||||
"--hf-clip-right": "0%",
|
||||
"--hf-to-x": "0px",
|
||||
"--hf-to-scale": 1,
|
||||
duration: 0.9,
|
||||
ease: "power3.inOut",
|
||||
},
|
||||
startTime,
|
||||
);
|
||||
tl.to(
|
||||
".hf-remocn-zoom-through-transition .from",
|
||||
{
|
||||
"--hf-from-x": "-70px",
|
||||
"--hf-from-scale": 0.96,
|
||||
"--hf-from-blur": "5px",
|
||||
duration: 0.9,
|
||||
ease: "power3.inOut",
|
||||
},
|
||||
startTime,
|
||||
);
|
||||
tl.fromTo(
|
||||
".hf-remocn-zoom-through-transition .fx",
|
||||
{ "--hf-fx-x": "-110%" },
|
||||
{ "--hf-fx-x": "110%", duration: 0.58, ease: "power2.inOut" },
|
||||
startTime + 0.18,
|
||||
);
|
||||
tl.fromTo(
|
||||
".hf-remocn-zoom-through-transition .rgb",
|
||||
{ "--hf-rgb-opacity": 0, "--hf-rgb-x": "-16px" },
|
||||
{
|
||||
"--hf-rgb-opacity": 1,
|
||||
"--hf-rgb-x": "16px",
|
||||
repeat: 3,
|
||||
yoyo: true,
|
||||
duration: 0.07,
|
||||
ease: "steps(1)",
|
||||
},
|
||||
startTime + 0.32,
|
||||
);
|
||||
tl.set({}, {}, 5);
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["zoom-through-transition-demo"] = tl;
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,80 +0,0 @@
|
||||
{
|
||||
"$schema": "https://hyperframes.heygen.com/schema/registry-item.json",
|
||||
"name": "zoom-through-transition",
|
||||
"type": "hyperframes:component",
|
||||
"title": "Zoom Through Transition",
|
||||
"description": "A transition that zooms through a focal card into the next scene.",
|
||||
"tags": ["transition-primitive", "remocn-port"],
|
||||
"variables": [
|
||||
{
|
||||
"id": "from-label",
|
||||
"type": "string",
|
||||
"role": "content",
|
||||
"label": "Outgoing label",
|
||||
"description": "Caption on the outgoing scene, the one on screen when the transition starts.",
|
||||
"default": "Before"
|
||||
},
|
||||
{
|
||||
"id": "to-label",
|
||||
"type": "string",
|
||||
"role": "content",
|
||||
"label": "Incoming label",
|
||||
"description": "Caption on the incoming scene, the one the timeline wipes into frame.",
|
||||
"default": "Zoom Through Transition"
|
||||
},
|
||||
{
|
||||
"id": "depth",
|
||||
"type": "enum",
|
||||
"role": "motion",
|
||||
"label": "Depth",
|
||||
"description": "Multiplies how far both scenes travel and how hard the outgoing one blurs, so the push covers a shorter or longer run in the same time.",
|
||||
"default": "standard",
|
||||
"options": [
|
||||
{
|
||||
"value": "close",
|
||||
"label": "Close"
|
||||
},
|
||||
{
|
||||
"value": "standard",
|
||||
"label": "Standard"
|
||||
},
|
||||
{
|
||||
"value": "far",
|
||||
"label": "Far"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "accent",
|
||||
"type": "enum",
|
||||
"role": "style",
|
||||
"label": "Accent",
|
||||
"description": "Theme token for the ring marking the incoming scene. Blue rides --accent, green --brand, violet --accent-2; each falls back to a neutral hairline.",
|
||||
"default": "blue",
|
||||
"options": [
|
||||
{
|
||||
"value": "blue",
|
||||
"label": "Blue"
|
||||
},
|
||||
{
|
||||
"value": "green",
|
||||
"label": "Green"
|
||||
},
|
||||
{
|
||||
"value": "violet",
|
||||
"label": "Violet"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "zoom-through-transition.html",
|
||||
"target": "compositions/components/zoom-through-transition.html",
|
||||
"type": "hyperframes:snippet"
|
||||
}
|
||||
],
|
||||
"preview": {
|
||||
"poster": "https://static.heygen.ai/hyperframes-oss/docs/images/catalog/components/zoom-through-transition.png"
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
Zoom Through Transition - a scene push that wipes the incoming scene through
|
||||
the outgoing one while the outgoing one drifts back and blurs.
|
||||
|
||||
Mount contract: MOUNTABLE SUB-COMPOSITION. The runtime clones only <template>
|
||||
contents; #root fills the host box (inset: 0, container-type: size), and the
|
||||
file registers one paused timeline under the literal "zoom-through-transition"
|
||||
key. Variables come from window.__hyperframes.getVariables().
|
||||
|
||||
This file owns its motion. It previously shipped as a fragment whose only
|
||||
executable timeline lived in demo.html, so an installed copy rendered the
|
||||
finished pose and never moved.
|
||||
|
||||
Variables (declared in data-composition-variables below):
|
||||
- from-label (string, default "Before"): caption on the outgoing scene.
|
||||
- to-label (string, default "Zoom Through Transition"): caption on the
|
||||
incoming scene, clipped out of frame until the wipe brings it in.
|
||||
- depth (close | standard | far, default standard): multiplies how far both
|
||||
scenes travel and how hard the outgoing one blurs. Every input it
|
||||
multiplies is zero at rest, so it collapses to the shipped pose there. It
|
||||
deliberately leaves the two scale tracks alone: the timeline drives those
|
||||
from their own start values, which a multiplier would distort.
|
||||
- accent (blue | green | violet, default blue): ink of the ring that marks
|
||||
the incoming scene. Both scenes are monochrome placeholder material; the
|
||||
ring is the one accent-coloured element. blue rides --accent, green rides
|
||||
--brand, violet rides --accent-2, and each falls back to a neutral
|
||||
hairline so an unthemed composition renders in black and white.
|
||||
|
||||
Envelope: the push starts at 0.35s (clamped to fit shorter durations), runs
|
||||
0.9s, then holds the incoming scene for whatever is left.
|
||||
-->
|
||||
<html
|
||||
lang="en"
|
||||
data-composition-id="zoom-through-transition"
|
||||
data-composition-duration="3"
|
||||
data-composition-variables='[
|
||||
{ "id": "from-label", "type": "string", "role": "content", "label": "Outgoing label", "description": "Caption on the outgoing scene, the one on screen when the transition starts.", "default": "Before" },
|
||||
{ "id": "to-label", "type": "string", "role": "content", "label": "Incoming label", "description": "Caption on the incoming scene, the one the timeline wipes into frame.", "default": "Zoom Through Transition" },
|
||||
{ "id": "depth", "type": "enum", "role": "motion", "label": "Depth", "description": "Multiplies how far both scenes travel and how hard the outgoing one blurs, so the push covers a shorter or longer run in the same time.", "default": "standard", "options": [{ "value": "close", "label": "Close" }, { "value": "standard", "label": "Standard" }, { "value": "far", "label": "Far" }] },
|
||||
{ "id": "accent", "type": "enum", "role": "style", "label": "Accent", "description": "Theme token for the ring marking the incoming scene. Blue rides --accent, green --brand, violet --accent-2; each falls back to a neutral hairline.", "default": "blue", "options": [{ "value": "blue", "label": "Blue" }, { "value": "green", "label": "Green" }, { "value": "violet", "label": "Violet" }] }
|
||||
]'
|
||||
>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Zoom Through Transition</title>
|
||||
</head>
|
||||
<body>
|
||||
<template>
|
||||
<div id="root" data-composition-id="zoom-through-transition" data-duration="3" data-fps="30">
|
||||
<style>
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Root fills the host-owned box; the scenes measure against it. */
|
||||
#root {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
container-type: size;
|
||||
isolation: isolate;
|
||||
overflow: hidden;
|
||||
background: #111827;
|
||||
}
|
||||
|
||||
.hf-remocn-zoom-through-transition {
|
||||
--hf-accent: var(--accent, rgba(255, 255, 255, 0.28));
|
||||
--hf-l1: rgba(255, 255, 255, 0.72);
|
||||
--hf-l3: rgba(255, 255, 255, 0.18);
|
||||
--hf-l4: rgba(255, 255, 255, 0.08);
|
||||
--hf-hair: rgba(255, 255, 255, 0.14);
|
||||
--hf-ink: #111827;
|
||||
--hf-muted: #6b7280;
|
||||
--hf-surface: #ffffff;
|
||||
color: var(--hf-ink);
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
}
|
||||
.hf-remocn-zoom-through-transition {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
background: #111827;
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .scene {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-weight: 900;
|
||||
font-size: 13.5cqmin;
|
||||
letter-spacing: -0.05em;
|
||||
color: #fff;
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .from {
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 255, 255, 0.04) 0 1px,
|
||||
transparent 1px 4px
|
||||
),
|
||||
var(--hf-l4);
|
||||
transform: translate(
|
||||
calc(var(--hf-from-x, 0px) * var(--hf-depth, 1)),
|
||||
calc(var(--hf-from-y, 0px) * var(--hf-depth, 1))
|
||||
)
|
||||
scale(var(--hf-from-scale, 1));
|
||||
filter: blur(calc(var(--hf-from-blur, 0px) * var(--hf-depth, 1)));
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .to {
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 255, 255, 0.05) 0 1px,
|
||||
transparent 1px 4px
|
||||
),
|
||||
var(--hf-l3);
|
||||
box-shadow: inset 0 0 0 2px var(--hf-accent);
|
||||
transform: translate(
|
||||
calc(var(--hf-to-x, 0px) * var(--hf-depth, 1)),
|
||||
calc(var(--hf-to-y, 0px) * var(--hf-depth, 1))
|
||||
)
|
||||
scale(var(--hf-to-scale, 1));
|
||||
clip-path: inset(
|
||||
var(--hf-clip-top, 0%) var(--hf-clip-right, 100%) var(--hf-clip-bottom, 0%)
|
||||
var(--hf-clip-left, 0%)
|
||||
);
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .fx {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.75), transparent);
|
||||
mix-blend-mode: screen;
|
||||
transform: translateX(var(--hf-fx-x, -110%));
|
||||
}
|
||||
.hf-remocn-zoom-through-transition .rgb {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: var(--hf-rgb-opacity, 0);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(239, 68, 68, 0.35),
|
||||
transparent,
|
||||
rgba(34, 211, 238, 0.35)
|
||||
);
|
||||
transform: translateX(var(--hf-rgb-x, 0px));
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="hf-remocn-zoom-through-transition">
|
||||
>
|
||||
<div class="scene from">Before</div>
|
||||
<div class="scene to">Zoom Through Transition</div>
|
||||
<div class="fx"></div>
|
||||
<div class="rgb"></div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var vars =
|
||||
window.__hyperframes && window.__hyperframes.getVariables
|
||||
? window.__hyperframes.getVariables()
|
||||
: {};
|
||||
|
||||
// Unrecognised overrides return to their declared defaults.
|
||||
var depths = { close: 0.55, standard: 1, far: 1.7 };
|
||||
// Each choice routes to a different contract token so the variable stays
|
||||
// meaningful under a theme rather than collapsing into one themed accent.
|
||||
var HAIRLINE = "rgba(255, 255, 255, 0.28)";
|
||||
var accents = {
|
||||
blue: "var(--accent, " + HAIRLINE + ")",
|
||||
green: "var(--brand, " + HAIRLINE + ")",
|
||||
violet: "var(--accent-2, " + HAIRLINE + ")",
|
||||
};
|
||||
|
||||
function pick(table, value, fallback) {
|
||||
return Object.prototype.hasOwnProperty.call(table, value) ? value : fallback;
|
||||
}
|
||||
|
||||
function label(value) {
|
||||
return typeof value === "string" && value !== "" ? value : null;
|
||||
}
|
||||
|
||||
var depth = depths[pick(depths, vars.depth, "standard")];
|
||||
var accent = accents[pick(accents, vars.accent, "blue")];
|
||||
var fromLabel = label(vars["from-label"]);
|
||||
var toLabel = label(vars["to-label"]);
|
||||
|
||||
var roots = document.querySelectorAll(".hf-remocn-zoom-through-transition");
|
||||
var mountRoot = document.getElementById("root");
|
||||
for (var i = 0; i < roots.length; i += 1) {
|
||||
var root = roots[i];
|
||||
root.style.setProperty("--hf-depth", String(depth));
|
||||
root.style.setProperty("--hf-accent", accent);
|
||||
|
||||
var fromScene = root.querySelector(".from");
|
||||
var toScene = root.querySelector(".to");
|
||||
if (fromLabel !== null && fromScene) {
|
||||
fromScene.textContent = fromLabel;
|
||||
}
|
||||
if (toLabel !== null && toScene) {
|
||||
toScene.textContent = toLabel;
|
||||
}
|
||||
}
|
||||
|
||||
// The motion used to live only in this file's demo page, so an installed
|
||||
// copy rendered the finished pose and never moved. The timeline belongs
|
||||
// with the markup it drives: build it here, paused, and register it under
|
||||
// this composition's own id so the runtime seeks it frame by frame.
|
||||
if (!mountRoot || !window.gsap) return;
|
||||
|
||||
var SELF = ".hf-remocn-zoom-through-transition";
|
||||
var duration = Math.max(0.001, parseFloat(mountRoot.dataset.duration || "3"));
|
||||
// The push reads as a transition only with a beat of the outgoing scene
|
||||
// before it. Clamped so the wipe always lands inside the duration.
|
||||
var PUSH = 0.9;
|
||||
var START = Math.max(0, Math.min(0.35, duration - PUSH));
|
||||
|
||||
var tl = window.gsap.timeline({ paused: true });
|
||||
|
||||
tl.fromTo(
|
||||
SELF + " .to",
|
||||
{ "--hf-clip-right": "100%", "--hf-to-x": "60px", "--hf-to-scale": 1.04 },
|
||||
{
|
||||
"--hf-clip-right": "0%",
|
||||
"--hf-to-x": "0px",
|
||||
"--hf-to-scale": 1,
|
||||
duration: PUSH,
|
||||
ease: "power3.inOut",
|
||||
},
|
||||
START,
|
||||
);
|
||||
tl.fromTo(
|
||||
SELF + " .from",
|
||||
{ "--hf-from-x": "0px", "--hf-from-scale": 1, "--hf-from-blur": "0px" },
|
||||
{
|
||||
"--hf-from-x": "-70px",
|
||||
"--hf-from-scale": 0.96,
|
||||
"--hf-from-blur": "5px",
|
||||
duration: PUSH,
|
||||
ease: "power3.inOut",
|
||||
},
|
||||
START,
|
||||
);
|
||||
tl.fromTo(
|
||||
SELF + " .fx",
|
||||
{ "--hf-fx-x": "-110%" },
|
||||
{ "--hf-fx-x": "110%", duration: 0.58, ease: "power2.inOut" },
|
||||
START + 0.18,
|
||||
);
|
||||
// repeat/yoyo resolves from absolute time on every seek, so the strobe is
|
||||
// reproducible at any frame rather than accumulated across ticks.
|
||||
tl.fromTo(
|
||||
SELF + " .rgb",
|
||||
{ "--hf-rgb-opacity": 0, "--hf-rgb-x": "-16px" },
|
||||
{
|
||||
"--hf-rgb-opacity": 1,
|
||||
"--hf-rgb-x": "16px",
|
||||
repeat: 3,
|
||||
yoyo: true,
|
||||
duration: 0.07,
|
||||
ease: "steps(1)",
|
||||
},
|
||||
START + 0.32,
|
||||
);
|
||||
|
||||
// HOLD: the incoming scene rests for whatever is left of the duration.
|
||||
tl.set({}, {}, duration);
|
||||
|
||||
tl.seek(0);
|
||||
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["zoom-through-transition"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</template>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user