mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-02 12:08:50 +00:00
feat(registry): add beat-freeze-cut
Beat-driven speed ramp, freeze-frame hit, and hard cut for music-led promos and montages. Contributed as #2957; applied here as content so the whole catalog set lands together. Verified by rendering: 6s, clean, deterministic (the one Math.random hit is a comment above a fixed pattern array). Opaque root, so no demo.html is needed for its catalog preview. Co-authored-by: akiyoshisan1218 <akiyoshisan1218@users.noreply.github.com>
This commit is contained in:
co-authored by
akiyoshisan1218
parent
35231e964d
commit
d3d286a1a5
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: "Beat Freeze Cut"
|
||||
description: "A beat-driven speed ramp, freeze-frame hit, and hard-cut sequence for music-led promos and montages."
|
||||
---
|
||||
|
||||
# Beat Freeze Cut
|
||||
|
||||
A beat-driven speed ramp, freeze-frame hit, and hard-cut sequence for music-led promos and montages.
|
||||
|
||||
`transition` `music` `beat-driven` `freeze-frame`
|
||||
|
||||
<video className="w-full aspect-video rounded-xl object-cover bg-zinc-100 dark:bg-zinc-800" src="https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/beat-freeze-cut.mp4" poster="https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/beat-freeze-cut.png" autoPlay muted loop playsInline />
|
||||
|
||||
## Install
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash Terminal
|
||||
npx hyperframes add beat-freeze-cut
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Details
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Type | Block |
|
||||
| Dimensions | 1920×1080 |
|
||||
| Duration | 6s |
|
||||
|
||||
## Files
|
||||
|
||||
| File | Target | Type |
|
||||
| --- | --- | --- |
|
||||
| `beat-freeze-cut.html` | `compositions/beat-freeze-cut.html` | hyperframes:composition |
|
||||
|
||||
## Usage
|
||||
|
||||
After installing, add the block to your host composition:
|
||||
|
||||
```html
|
||||
<div data-composition-id="beat-freeze-cut" data-composition-src="compositions/beat-freeze-cut.html" data-start="0" data-duration="6" data-track-index="1" data-width="1920" data-height="1080"></div>
|
||||
```
|
||||
@@ -303,6 +303,7 @@
|
||||
{
|
||||
"group": "CSS Transitions",
|
||||
"pages": [
|
||||
"catalog/blocks/beat-freeze-cut",
|
||||
"catalog/blocks/hw-scribble-transition",
|
||||
"catalog/blocks/mk-clone-wall-transition",
|
||||
"catalog/blocks/organic-light-leak-overlay",
|
||||
|
||||
@@ -27,6 +27,20 @@
|
||||
"href": "/catalog/blocks/apple-money-count",
|
||||
"preview": "https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/apple-money-count.png"
|
||||
},
|
||||
{
|
||||
"name": "beat-freeze-cut",
|
||||
"type": "block",
|
||||
"title": "Beat Freeze Cut",
|
||||
"description": "A beat-driven speed ramp, freeze-frame hit, and hard-cut sequence for music-led promos and montages.",
|
||||
"tags": [
|
||||
"transition",
|
||||
"music",
|
||||
"beat-driven",
|
||||
"freeze-frame"
|
||||
],
|
||||
"href": "/catalog/blocks/beat-freeze-cut",
|
||||
"preview": "https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/beat-freeze-cut.png"
|
||||
},
|
||||
{
|
||||
"name": "blue-sweater-intro-video",
|
||||
"type": "block",
|
||||
|
||||
@@ -0,0 +1,879 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<title>Beat Freeze Cut</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:wght@500;600;700;800;900&display=block"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0b0d10;
|
||||
}
|
||||
|
||||
/*
|
||||
EDIT / STUDIO PARAMS
|
||||
────────────────────
|
||||
Studio color params (CSS custom properties on the root):
|
||||
--bg-color default #0B0D10
|
||||
--accent-color default #00E5C7
|
||||
|
||||
Numeric / string params (beat times, labels, intensity) are NOT in the
|
||||
formal registry params schema today (only color keys are used by
|
||||
existing blocks). Edit the CONFIG object in the script below instead.
|
||||
*/
|
||||
|
||||
#bfc-root {
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
--bg-color: #0b0d10;
|
||||
--accent-color: #00e5c7;
|
||||
--bfc-ink: #f4f6f8;
|
||||
--bfc-muted: #a0a8b0;
|
||||
--bfc-panel: #14181f;
|
||||
--bfc-panel-2: #1a2029;
|
||||
--bfc-line: rgba(255, 255, 255, 0.08);
|
||||
font-family:
|
||||
"Inter",
|
||||
system-ui,
|
||||
-apple-system,
|
||||
sans-serif;
|
||||
color: var(--bfc-ink);
|
||||
}
|
||||
|
||||
#bfc-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 80% 60% at 50% 40%, rgba(0, 229, 199, 0.07) 0%, transparent 55%),
|
||||
radial-gradient(
|
||||
ellipse 50% 40% at 80% 80%,
|
||||
rgba(255, 255, 255, 0.03) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
var(--bg-color);
|
||||
}
|
||||
|
||||
#bfc-grid {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.22;
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
|
||||
background-size: 80px 80px;
|
||||
mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, #000 20%, transparent 75%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#bfc-stage {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform-origin: 50% 48%;
|
||||
will-change: transform, filter;
|
||||
}
|
||||
|
||||
#bfc-shot-a,
|
||||
#bfc-shot-b {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#bfc-shot-b {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* ── Shot A: single product card hero ── */
|
||||
#bfc-a-crop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
#bfc-a-card {
|
||||
position: relative;
|
||||
width: 680px;
|
||||
height: 720px;
|
||||
border-radius: 36px;
|
||||
background:
|
||||
linear-gradient(160deg, rgba(255, 255, 255, 0.06) 0%, transparent 40%),
|
||||
linear-gradient(180deg, var(--bfc-panel-2) 0%, var(--bfc-panel) 100%);
|
||||
border: 1px solid var(--bfc-line);
|
||||
box-shadow:
|
||||
0 40px 120px rgba(0, 0, 0, 0.55),
|
||||
0 0 0 1px rgba(0, 229, 199, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
||||
overflow: hidden;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
#bfc-a-card-glow {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 28%;
|
||||
width: 420px;
|
||||
height: 420px;
|
||||
margin-left: -210px;
|
||||
margin-top: -210px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(0, 229, 199, 0.28) 0%, transparent 68%);
|
||||
opacity: 0.85;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#bfc-a-wave {
|
||||
position: absolute;
|
||||
left: 64px;
|
||||
right: 64px;
|
||||
top: 120px;
|
||||
height: 220px;
|
||||
}
|
||||
|
||||
#bfc-a-wave svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#bfc-a-wave-path {
|
||||
fill: none;
|
||||
stroke: var(--accent-color);
|
||||
stroke-width: 4;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
#bfc-a-wave-fill {
|
||||
fill: var(--accent-color);
|
||||
opacity: 0.12;
|
||||
}
|
||||
|
||||
#bfc-a-bars {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 80px;
|
||||
bottom: 160px;
|
||||
height: 96px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.bfc-bar {
|
||||
flex: 1;
|
||||
border-radius: 6px 6px 2px 2px;
|
||||
background: linear-gradient(180deg, var(--accent-color) 0%, rgba(0, 229, 199, 0.25) 100%);
|
||||
transform-origin: 50% 100%;
|
||||
height: 40%;
|
||||
}
|
||||
|
||||
#bfc-a-meta {
|
||||
position: absolute;
|
||||
left: 64px;
|
||||
right: 64px;
|
||||
bottom: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#bfc-a-kicker {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--bfc-muted);
|
||||
}
|
||||
|
||||
#bfc-a-pill {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #04120f;
|
||||
background: var(--accent-color);
|
||||
padding: 8px 16px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
/* ── Shot B: split layout, higher info density ── */
|
||||
#bfc-b-layout {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1.05fr 0.95fr;
|
||||
gap: 48px;
|
||||
padding: 100px 110px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#bfc-b-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
transform-origin: 0% 50%;
|
||||
}
|
||||
|
||||
#bfc-b-eyebrow {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.22em;
|
||||
text-transform: uppercase;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
#bfc-b-title {
|
||||
font-size: 128px;
|
||||
font-weight: 900;
|
||||
line-height: 0.92;
|
||||
letter-spacing: -0.04em;
|
||||
text-transform: uppercase;
|
||||
color: var(--bfc-ink);
|
||||
}
|
||||
|
||||
#bfc-b-sub {
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
color: var(--bfc-muted);
|
||||
max-width: 520px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
#bfc-b-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.bfc-b-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24px;
|
||||
padding: 28px 32px;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--bfc-panel-2), var(--bfc-panel));
|
||||
border: 1px solid var(--bfc-line);
|
||||
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.bfc-b-card-label {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--bfc-muted);
|
||||
}
|
||||
|
||||
.bfc-b-card-value {
|
||||
font-size: 42px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.03em;
|
||||
color: var(--bfc-ink);
|
||||
}
|
||||
|
||||
.bfc-b-card-value.accent {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
#bfc-b-accent-bar {
|
||||
width: 120px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background: var(--accent-color);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ── Intro / transient typography ── */
|
||||
#bfc-intro {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 72px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
z-index: 20;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#bfc-intro-label {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.28em;
|
||||
text-transform: uppercase;
|
||||
color: var(--bfc-muted);
|
||||
padding: 10px 18px;
|
||||
border: 1px solid var(--bfc-line);
|
||||
border-radius: 999px;
|
||||
background: rgba(11, 13, 16, 0.55);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
#bfc-hit-type {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
z-index: 30;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#bfc-hit-type-text {
|
||||
font-size: 160px;
|
||||
font-weight: 900;
|
||||
letter-spacing: -0.04em;
|
||||
text-transform: uppercase;
|
||||
color: var(--bfc-ink);
|
||||
text-shadow:
|
||||
0 0 40px rgba(0, 229, 199, 0.35),
|
||||
0 8px 40px rgba(0, 0, 0, 0.55);
|
||||
-webkit-text-stroke: 2px rgba(0, 0, 0, 0.35);
|
||||
paint-order: stroke fill;
|
||||
}
|
||||
|
||||
/* ── Freeze frame treatment ── */
|
||||
#bfc-freeze {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 25;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#bfc-freeze-outline {
|
||||
position: absolute;
|
||||
inset: 48px;
|
||||
border: 3px solid var(--accent-color);
|
||||
border-radius: 8px;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(0, 229, 199, 0.25),
|
||||
inset 0 0 0 1px rgba(0, 229, 199, 0.15),
|
||||
0 0 48px rgba(0, 229, 199, 0.2);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#bfc-freeze-flash {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: #ffffff;
|
||||
opacity: 0;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
#bfc-freeze-contour {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(90deg, transparent 0%, rgba(0, 229, 199, 0.08) 48%, transparent 52%),
|
||||
radial-gradient(ellipse 40% 55% at 50% 48%, transparent 40%, rgba(0, 229, 199, 0.18) 100%);
|
||||
opacity: 0;
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
#bfc-freeze-badge {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
right: 96px;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: #04120f;
|
||||
background: var(--accent-color);
|
||||
padding: 10px 18px;
|
||||
border-radius: 6px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* ── Hard-cut connector (directional stretch / blur) ── */
|
||||
#bfc-cut {
|
||||
position: absolute;
|
||||
inset: -8% -20%;
|
||||
pointer-events: none;
|
||||
z-index: 40;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
rgba(0, 229, 199, 0.12) 35%,
|
||||
rgba(255, 255, 255, 0.55) 50%,
|
||||
rgba(0, 229, 199, 0.12) 65%,
|
||||
transparent 100%
|
||||
);
|
||||
filter: blur(18px);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
#bfc-vignette {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 15;
|
||||
background: radial-gradient(
|
||||
ellipse 75% 70% at 50% 50%,
|
||||
transparent 45%,
|
||||
rgba(0, 0, 0, 0.55) 100%
|
||||
);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
#bfc-driver {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
id="bfc-root"
|
||||
data-composition-id="beat-freeze-cut"
|
||||
data-start="0"
|
||||
data-duration="6"
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<div id="bfc-bg" aria-hidden="true"></div>
|
||||
<div id="bfc-grid" aria-hidden="true"></div>
|
||||
|
||||
<div id="bfc-stage">
|
||||
<!-- Shot A -->
|
||||
<div id="bfc-shot-a">
|
||||
<div id="bfc-a-crop" data-layout-allow-overflow>
|
||||
<div id="bfc-a-card" data-layout-allow-overflow>
|
||||
<div id="bfc-a-card-glow" aria-hidden="true"></div>
|
||||
<div id="bfc-a-wave" aria-hidden="true">
|
||||
<svg viewBox="0 0 592 220" preserveAspectRatio="none">
|
||||
<path
|
||||
id="bfc-a-wave-fill"
|
||||
d="M0,160 C40,150 60,90 100,100 C140,110 160,40 200,55 C240,70 260,150 300,140 C340,130 360,30 400,45 C440,60 460,130 500,120 C540,110 560,70 592,80 L592,220 L0,220 Z"
|
||||
/>
|
||||
<path
|
||||
id="bfc-a-wave-path"
|
||||
d="M0,160 C40,150 60,90 100,100 C140,110 160,40 200,55 C240,70 260,150 300,140 C340,130 360,30 400,45 C440,60 460,130 500,120 C540,110 560,70 592,80"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="bfc-a-bars" aria-hidden="true">
|
||||
<div class="bfc-bar" id="bfc-bar-0" style="height: 34%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-1" style="height: 58%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-2" style="height: 42%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-3" style="height: 78%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-4" style="height: 52%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-5" style="height: 88%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-6" style="height: 46%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-7" style="height: 64%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-8" style="height: 36%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-9" style="height: 72%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-10" style="height: 48%"></div>
|
||||
<div class="bfc-bar" id="bfc-bar-11" style="height: 92%"></div>
|
||||
</div>
|
||||
<div id="bfc-a-meta">
|
||||
<span id="bfc-a-kicker">MUSIC PROMO</span>
|
||||
<span id="bfc-a-pill">LIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shot B -->
|
||||
<div id="bfc-shot-b">
|
||||
<div id="bfc-b-layout">
|
||||
<div id="bfc-b-left">
|
||||
<div id="bfc-b-eyebrow">Next shot</div>
|
||||
<div id="bfc-b-title">HARD<br />CUT</div>
|
||||
<div id="bfc-b-accent-bar" aria-hidden="true"></div>
|
||||
<div id="bfc-b-sub">
|
||||
Beat-locked freeze, then cut. Built for music-led promos and montages.
|
||||
</div>
|
||||
</div>
|
||||
<div id="bfc-b-right">
|
||||
<div class="bfc-b-card" id="bfc-b-card-0">
|
||||
<span class="bfc-b-card-label">Ramp</span>
|
||||
<span class="bfc-b-card-value accent">1.35→2.2</span>
|
||||
</div>
|
||||
<div class="bfc-b-card" id="bfc-b-card-1">
|
||||
<span class="bfc-b-card-label">Freeze</span>
|
||||
<span class="bfc-b-card-value">0.8s</span>
|
||||
</div>
|
||||
<div class="bfc-b-card" id="bfc-b-card-2">
|
||||
<span class="bfc-b-card-label">Cut</span>
|
||||
<span class="bfc-b-card-value accent">3.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bfc-vignette" aria-hidden="true"></div>
|
||||
|
||||
<div id="bfc-intro" aria-hidden="true">
|
||||
<span id="bfc-intro-label">ON THE BEAT</span>
|
||||
</div>
|
||||
|
||||
<div id="bfc-hit-type" aria-hidden="true">
|
||||
<span id="bfc-hit-type-text">DROP</span>
|
||||
</div>
|
||||
|
||||
<div id="bfc-freeze" aria-hidden="true">
|
||||
<div id="bfc-freeze-flash"></div>
|
||||
<div id="bfc-freeze-contour"></div>
|
||||
<div id="bfc-freeze-outline"></div>
|
||||
<div id="bfc-freeze-badge">FREEZE</div>
|
||||
</div>
|
||||
|
||||
<div id="bfc-cut" aria-hidden="true"></div>
|
||||
|
||||
<div id="bfc-driver" class="clip" data-start="0" data-duration="6" data-track-index="0"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
// ── EDIT ME (not Studio params — see HTML comment) ──────────────
|
||||
var CONFIG = {
|
||||
primaryLabel: "DROP",
|
||||
secondaryLabel: "ON THE BEAT",
|
||||
beat1: 0.7,
|
||||
beat2: 2.2,
|
||||
freezeTime: 2.2,
|
||||
intensity: 1.0,
|
||||
};
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
|
||||
var DURATION = 6;
|
||||
var intensity = Math.max(0.6, Math.min(1.4, Number(CONFIG.intensity) || 1));
|
||||
var beat1 = Number(CONFIG.beat1) || 0.7;
|
||||
var beat2 = Number(CONFIG.beat2) || 2.2;
|
||||
var freezeAt = Number(CONFIG.freezeTime) || beat2;
|
||||
var cutAt = 3.0;
|
||||
var beat3 = 4.7;
|
||||
var holdAt = 5.2;
|
||||
|
||||
var root = document.getElementById("bfc-root");
|
||||
var stage = document.getElementById("bfc-stage");
|
||||
var shotA = document.getElementById("bfc-shot-a");
|
||||
var shotB = document.getElementById("bfc-shot-b");
|
||||
var aCrop = document.getElementById("bfc-a-crop");
|
||||
var aCard = document.getElementById("bfc-a-card");
|
||||
var intro = document.getElementById("bfc-intro");
|
||||
var introLabel = document.getElementById("bfc-intro-label");
|
||||
var hitType = document.getElementById("bfc-hit-type");
|
||||
var hitText = document.getElementById("bfc-hit-type-text");
|
||||
var freeze = document.getElementById("bfc-freeze");
|
||||
var freezeOutline = document.getElementById("bfc-freeze-outline");
|
||||
var freezeFlash = document.getElementById("bfc-freeze-flash");
|
||||
var freezeContour = document.getElementById("bfc-freeze-contour");
|
||||
var freezeBadge = document.getElementById("bfc-freeze-badge");
|
||||
var cutFx = document.getElementById("bfc-cut");
|
||||
var bLeft = document.getElementById("bfc-b-left");
|
||||
var bCards = [
|
||||
document.getElementById("bfc-b-card-0"),
|
||||
document.getElementById("bfc-b-card-1"),
|
||||
document.getElementById("bfc-b-card-2"),
|
||||
];
|
||||
var bars = [];
|
||||
for (var bi = 0; bi < 12; bi++) {
|
||||
bars.push(document.getElementById("bfc-bar-" + bi));
|
||||
}
|
||||
|
||||
// Apply editable labels
|
||||
if (hitText) hitText.textContent = CONFIG.primaryLabel || "DROP";
|
||||
if (introLabel) introLabel.textContent = CONFIG.secondaryLabel || "ON THE BEAT";
|
||||
|
||||
// Accent color from CSS var → freeze/glow that use hardcoded rgba fallbacks
|
||||
// stay coherent because stroke/fill already use var(--accent-color).
|
||||
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
// Initial states (no CSS transform conflicts on animated props)
|
||||
gsap.set(stage, { scale: 1, x: 0, y: 0, filter: "blur(0px) brightness(1)" });
|
||||
gsap.set(aCrop, { scale: 1, x: 0, y: 0 });
|
||||
// Card visible at t=0 so catalog snapshots are never a black frame
|
||||
gsap.set(aCard, { scale: 0.9, y: 20, opacity: 1 });
|
||||
gsap.set(shotA, { opacity: 1, visibility: "visible" });
|
||||
gsap.set(shotB, { opacity: 0, visibility: "hidden" });
|
||||
gsap.set(intro, { opacity: 0, visibility: "hidden", y: -12 });
|
||||
gsap.set(hitType, { opacity: 0, visibility: "hidden", scale: 1.15 });
|
||||
gsap.set(freeze, { opacity: 0, visibility: "hidden" });
|
||||
gsap.set([freezeOutline, freezeFlash, freezeContour, freezeBadge], { opacity: 0 });
|
||||
gsap.set(cutFx, { opacity: 0, visibility: "hidden", scaleX: 0.4, x: -200 });
|
||||
gsap.set(bLeft, { opacity: 0, x: -48 });
|
||||
gsap.set(bCards, { opacity: 0, x: 40 });
|
||||
gsap.set(bars, { scaleY: 0.55 });
|
||||
|
||||
// Full duration anchor (seek-safe length)
|
||||
tl.to({}, { duration: DURATION, ease: "none" }, 0);
|
||||
|
||||
// ── 0.00–0.70: intro push-in + secondary type ──
|
||||
tl.to(aCard, { scale: 1, y: 0, duration: 0.55, ease: "power3.out" }, 0);
|
||||
tl.to(stage, { scale: 1 + 0.04 * intensity, duration: 0.7, ease: "power1.out" }, 0);
|
||||
tl.to(bars, { scaleY: 1, duration: 0.5, ease: "power2.out", stagger: 0.02 }, 0.12);
|
||||
tl.set(intro, { visibility: "visible" }, 0.12);
|
||||
tl.to(intro, { opacity: 1, y: 0, duration: 0.28, ease: "power2.out" }, 0.12);
|
||||
tl.to(intro, { opacity: 0, y: -8, duration: 0.18, ease: "power2.in" }, 0.52);
|
||||
tl.set(intro, { visibility: "hidden", opacity: 0 }, 0.7);
|
||||
|
||||
// ── 0.70–1.35: beat 1 — hard reframe ──
|
||||
tl.to(
|
||||
aCrop,
|
||||
{
|
||||
scale: 1 + 0.18 * intensity,
|
||||
x: -80 * intensity,
|
||||
y: 24 * intensity,
|
||||
duration: 0.22,
|
||||
ease: "power4.out",
|
||||
},
|
||||
beat1,
|
||||
);
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
scale: 1.08 * intensity > 1.2 ? 1.2 : 1 + 0.08 * intensity,
|
||||
duration: 0.28,
|
||||
ease: "expo.out",
|
||||
},
|
||||
beat1,
|
||||
);
|
||||
tl.to(
|
||||
bars,
|
||||
{
|
||||
scaleY: function (i) {
|
||||
// Deterministic bar pattern (no Math.random)
|
||||
var pattern = [0.55, 1.15, 0.7, 1.35, 0.9, 1.4, 0.65, 1.1, 0.5, 1.25, 0.8, 1.45];
|
||||
return pattern[i % pattern.length];
|
||||
},
|
||||
duration: 0.18,
|
||||
ease: "power3.out",
|
||||
stagger: 0.01,
|
||||
},
|
||||
beat1,
|
||||
);
|
||||
|
||||
// ── 1.35–2.20: speed ramp into freeze ──
|
||||
var rampStart = 1.35;
|
||||
var rampDur = Math.max(0.2, freezeAt - rampStart);
|
||||
tl.to(
|
||||
aCrop,
|
||||
{
|
||||
scale: 1.28 * (0.9 + 0.1 * intensity),
|
||||
x: 28 * intensity,
|
||||
y: -12 * intensity,
|
||||
duration: rampDur,
|
||||
ease: "power3.in",
|
||||
},
|
||||
rampStart,
|
||||
);
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
scale: 1.12,
|
||||
filter: "blur(0px) brightness(1.08)",
|
||||
duration: rampDur,
|
||||
ease: "power2.in",
|
||||
},
|
||||
rampStart,
|
||||
);
|
||||
tl.to(
|
||||
bars,
|
||||
{
|
||||
scaleY: 1.55,
|
||||
duration: rampDur * 0.85,
|
||||
ease: "power2.in",
|
||||
stagger: { each: 0.012, from: "center" },
|
||||
},
|
||||
rampStart,
|
||||
);
|
||||
|
||||
// ── 2.20–3.00: freeze hit (snap-on for seek/snapshot stability) ──
|
||||
tl.set(freeze, { visibility: "visible", opacity: 1 }, freezeAt);
|
||||
tl.set(freezeOutline, { opacity: 1 }, freezeAt);
|
||||
tl.set(freezeContour, { opacity: 0.85 }, freezeAt);
|
||||
tl.set(freezeBadge, { opacity: 1 }, freezeAt);
|
||||
tl.set(hitType, { visibility: "visible", opacity: 1, scale: 1 }, freezeAt);
|
||||
// Hold crop/stage where ramp ended
|
||||
tl.to(aCrop, { duration: 0.01, ease: "none" }, freezeAt);
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
scale: 1.12,
|
||||
filter: "blur(0px) brightness(1.15)",
|
||||
duration: 0.05,
|
||||
ease: "power4.out",
|
||||
},
|
||||
freezeAt,
|
||||
);
|
||||
// Single exposure flash (not a strobe sequence)
|
||||
tl.fromTo(
|
||||
freezeFlash,
|
||||
{ opacity: 0.55 * intensity },
|
||||
{ opacity: 0, duration: 0.28, ease: "power2.out" },
|
||||
freezeAt,
|
||||
);
|
||||
tl.to(
|
||||
hitType,
|
||||
{ opacity: 0, scale: 0.96, duration: 0.2, ease: "power2.in" },
|
||||
freezeAt + 0.55,
|
||||
);
|
||||
tl.set(hitType, { visibility: "hidden", opacity: 0 }, freezeAt + 0.78);
|
||||
// Soft settle of freeze dressing before cut
|
||||
tl.to(
|
||||
[freezeOutline, freezeContour, freezeBadge],
|
||||
{ opacity: 0.75, duration: 0.35, ease: "sine.out" },
|
||||
freezeAt + 0.35,
|
||||
);
|
||||
|
||||
// ── 3.00–3.35: hard cut connector ──
|
||||
tl.set(cutFx, { visibility: "visible" }, cutAt);
|
||||
tl.fromTo(
|
||||
cutFx,
|
||||
{ opacity: 0, scaleX: 0.35, x: -280 },
|
||||
{
|
||||
opacity: 0.95,
|
||||
scaleX: 1.6,
|
||||
x: 120,
|
||||
duration: 0.12,
|
||||
ease: "power4.in",
|
||||
},
|
||||
cutAt,
|
||||
);
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
filter: "blur(14px) brightness(1.35)",
|
||||
scaleX: 1.35,
|
||||
scaleY: 0.92,
|
||||
duration: 0.12,
|
||||
ease: "power3.in",
|
||||
},
|
||||
cutAt,
|
||||
);
|
||||
// Switch shots mid-cut — shot B content lands immediately (no black gap)
|
||||
var switchAt = cutAt + 0.14;
|
||||
tl.set(shotA, { opacity: 0, visibility: "hidden" }, switchAt);
|
||||
tl.set(shotB, { opacity: 1, visibility: "visible" }, switchAt);
|
||||
tl.set(hitType, { opacity: 0, visibility: "hidden" }, switchAt);
|
||||
tl.set(
|
||||
[freeze, freezeOutline, freezeFlash, freezeContour, freezeBadge],
|
||||
{ opacity: 0, visibility: "hidden" },
|
||||
switchAt,
|
||||
);
|
||||
tl.set(freeze, { visibility: "hidden" }, switchAt);
|
||||
// Shot B content visible on switch (offset settles after)
|
||||
tl.set(bLeft, { opacity: 1, x: -24 }, switchAt);
|
||||
tl.set(bCards, { opacity: 1, x: 24 }, switchAt);
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
filter: "blur(0px) brightness(1)",
|
||||
scale: 1,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
duration: 0.18,
|
||||
ease: "power3.out",
|
||||
},
|
||||
switchAt,
|
||||
);
|
||||
tl.to(cutFx, { opacity: 0, x: 360, duration: 0.16, ease: "power2.out" }, cutAt + 0.16);
|
||||
tl.set(cutFx, { visibility: "hidden", opacity: 0 }, cutAt + 0.34);
|
||||
|
||||
// ── after switch: shot B settle (no scale overlap with recover) ──
|
||||
tl.to(bLeft, { x: 0, duration: 0.4, ease: "power3.out" }, switchAt);
|
||||
tl.to(
|
||||
bCards,
|
||||
{
|
||||
x: 0,
|
||||
duration: 0.38,
|
||||
ease: "power3.out",
|
||||
stagger: 0.06,
|
||||
},
|
||||
switchAt + 0.04,
|
||||
);
|
||||
tl.to(stage, { scale: 1.02, duration: 1.17, ease: "sine.out" }, switchAt + 0.18);
|
||||
|
||||
// ── 4.70–5.20: final beat punch-in ──
|
||||
tl.to(
|
||||
stage,
|
||||
{
|
||||
scale: 1.08 * (0.9 + 0.1 * intensity),
|
||||
duration: 0.14,
|
||||
ease: "power4.out",
|
||||
},
|
||||
beat3,
|
||||
);
|
||||
tl.to(
|
||||
bCards[1],
|
||||
{
|
||||
scale: 1.04,
|
||||
duration: 0.12,
|
||||
ease: "power3.out",
|
||||
},
|
||||
beat3,
|
||||
);
|
||||
tl.to(
|
||||
bCards[1],
|
||||
{
|
||||
scale: 1,
|
||||
duration: 0.22,
|
||||
ease: "power2.out",
|
||||
},
|
||||
beat3 + 0.14,
|
||||
);
|
||||
// Micro freeze feel: brief hold of scale
|
||||
tl.to(
|
||||
stage,
|
||||
{ scale: 1.08 * (0.9 + 0.1 * intensity), duration: 0.2, ease: "none" },
|
||||
beat3 + 0.14,
|
||||
);
|
||||
|
||||
// ── 5.20–6.00: hold readable end card (≥0.8s) ──
|
||||
tl.to(stage, { scale: 1.03, duration: 0.35, ease: "power2.out" }, holdAt);
|
||||
// Ensure transient layers stay dead through end
|
||||
tl.set(intro, { opacity: 0, visibility: "hidden" }, holdAt);
|
||||
tl.set(hitType, { opacity: 0, visibility: "hidden" }, holdAt);
|
||||
tl.set(freeze, { opacity: 0, visibility: "hidden" }, holdAt);
|
||||
tl.set(cutFx, { opacity: 0, visibility: "hidden" }, holdAt);
|
||||
|
||||
window.__timelines["beat-freeze-cut"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "https://hyperframes.heygen.com/schema/registry-item.json",
|
||||
"name": "beat-freeze-cut",
|
||||
"type": "hyperframes:block",
|
||||
"title": "Beat Freeze Cut",
|
||||
"description": "A beat-driven speed ramp, freeze-frame hit, and hard-cut sequence for music-led promos and montages.",
|
||||
"tags": ["transition", "music", "beat-driven", "freeze-frame"],
|
||||
"dimensions": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
"duration": 6,
|
||||
"files": [
|
||||
{
|
||||
"path": "beat-freeze-cut.html",
|
||||
"target": "compositions/beat-freeze-cut.html",
|
||||
"type": "hyperframes:composition"
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"key": "--bg-color",
|
||||
"label": "Background",
|
||||
"type": "color",
|
||||
"default": "#0B0D10"
|
||||
},
|
||||
{
|
||||
"key": "--accent-color",
|
||||
"label": "Accent",
|
||||
"type": "color",
|
||||
"default": "#00E5C7"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -702,6 +702,10 @@
|
||||
{
|
||||
"name": "hw-underline",
|
||||
"type": "hyperframes:component"
|
||||
},
|
||||
{
|
||||
"name": "beat-freeze-cut",
|
||||
"type": "hyperframes:block"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user