// video-scenes.jsx — kinetic typography scenes for "Für Branding mit Emotionen" // Uses engine globals: useTime, Easing, interpolate, animate, clamp. const { useTime: vUseTime, Easing: E, interpolate: vInterp, animate: vAnim, clamp: vClamp } = window; const VC = { bg: '#1A1A1A', bg2: '#212121', accent: '#C0392B', accent2: '#D35400', text: '#ECECEC', dim: '#8C8C8C', faint: '#5A5A5A', }; const DISP = "'Barlow Condensed', sans-serif"; const SEMI = "'Barlow Semi Condensed', sans-serif"; const BODY = "'Barlow', sans-serif"; // ── Scene wrapper: opacity envelope + centered full frame ─────────────────── function SceneWrap({ start, end, fadeIn = 0.5, fadeOut = 0.5, bg, children }) { const t = vUseTime(); if (t < start - 0.0001 || t > end + 0.0001) return null; const lt = t - start; const dur = end - start; let op = 1; if (fadeIn > 0 && lt < fadeIn) op = E.easeInOutSine(vClamp(lt / fadeIn, 0, 1)); else if (fadeOut > 0 && lt > dur - fadeOut) op = E.easeInOutSine(vClamp((dur - lt) / fadeOut, 0, 1)); return (
{children(lt, dur, t)}
); } const Kicker = ({ text, color = VC.dim, size = 46, ...rest }) => (
{text}
); // ── SCENE 1 — MANCHMAL LAUT. (loud: slam + shake + sound blasts) ──────────── function SceneLaut({ start, end }) { return ( {(lt, dur, t) => { // entry slam const scale = vAnim({ from: 1.6, to: 1, start: 0, end: 0.55, ease: E.easeOutBack })(lt); const introOp = vClamp(lt / 0.18, 0, 1); // decaying vibration const decay = vClamp(1 - (lt - 0.55) / 2.6, 0, 1); const shakeX = lt > 0.55 ? Math.sin(t * 58) * 5 * decay : 0; const shakeY = lt > 0.55 ? Math.cos(t * 71) * 4 * decay : 0; // flash const flash = vClamp(1 - lt / 0.3, 0, 1) * 0.55; const rings = [0, 1, 2, 3, 4]; return (
{/* sound blast rings */} {rings.map((i) => { const phase = ((lt * 0.85) + i * 0.26) % 1; const d = phase * 1700; const o = (1 - phase) * 0.4 * vClamp(lt / 0.4, 0, 1); return
; })}
LAUT.
); }} ); } // ── SCENE 2 — MANCHMAL LEISE. (quiet: soft blur-in, drift, hush) ──────────── function SceneLeise({ start, end }) { return ( {(lt, dur, t) => { const blur = vClamp(10 - lt * 9, 0, 10); const drift = -lt * 6; // slow upward drift const track = vInterp([0, 1.2], [0.34, 0.5], E.easeOutCubic)(lt); const lineW = vAnim({ from: 0, to: 360, start: 0.3, end: 1.6, ease: E.easeOutCubic })(lt); return (
leise.
); }} ); } // ── SCENE 3 — MANCHMAL KRAFTVOLL. (powerful: drive-in + speed lines) ──────── function SceneKraftvoll({ start, end }) { return ( {(lt, dur, t) => { const x = vAnim({ from: -620, to: 0, start: 0, end: 0.6, ease: E.easeOutBack })(lt); const zoom = vInterp([0.6, dur], [1, 1.04], E.easeOutSine)(lt); const op = vClamp(lt / 0.15, 0, 1); const lines = [0, 1, 2, 3, 4, 5, 6, 7]; return (
{/* diagonal speed lines */}
{lines.map((i) => { const phase = ((t * 0.55) + i * 0.135) % 1; const lx = -400 + phase * 3000; const o = Math.sin(phase * Math.PI) * 0.5; const len = 180 + (i % 3) * 160; return
; })}
KRAFTVOLL.
); }} ); } // ── SCENE 4 — MANCHMAL RUHIGER. (calm: slow waves, settle) ────────────────── function CalmWaves({ t }) { const W = 1920, H = 1080, mid = 640; const mk = (amp, speed, phase, stroke, op, yoff) => { let d = `M 0 ${mid + yoff}`; for (let x = 0; x <= W; x += 40) { const y = mid + yoff + Math.sin((x / W) * Math.PI * 3 + t * speed + phase) * amp; d += ` L ${x} ${y}`; } return ; }; return ( {mk(34, 0.6, 0, VC.accent, 0.22, 150)} {mk(26, 0.8, 1.4, VC.accent2, 0.18, 200)} {mk(20, 0.45, 3.1, '#6a8caf', 0.16, 250)} ); } function SceneRuhiger({ start, end }) { return ( {(lt, dur, t) => { const track = vInterp([0, 1.5], [0.28, 0.4], E.easeOutCubic)(lt); const rise = vAnim({ from: 22, to: 0, start: 0, end: 1.4, ease: E.easeOutCubic })(lt); return (
ruhiger.
); }}
); } // ── Tacho mark (bridge to website) ────────────────────────────────────────── const polar = (cx, cy, r, deg) => { const a = (deg - 90) * Math.PI / 180; return [cx + r * Math.cos(a), cy + r * Math.sin(a)]; }; function arcPath(cx, cy, r, d0, d1) { const [x0, y0] = polar(cx, cy, r, d0), [x1, y1] = polar(cx, cy, r, d1); const large = (d1 - d0) > 180 ? 1 : 0; return `M ${x0} ${y0} A ${r} ${r} 0 ${large} 1 ${x1} ${y1}`; } const tachoAngle = (v) => 225 + (v / 8000) * 270; function TachoMark({ prog }) { const cx = 130, cy = 128, R = 100; const ang = 225 + (tachoAngle(7900) - 225) * E.easeOutCubic(prog); const ticks = []; for (let v = 0; v <= 8000; v += 1000) { const deg = tachoAngle(v); const red = v >= 6500; const [ox, oy] = polar(cx, cy, R, deg); const [ix, iy] = polar(cx, cy, R - 16, deg); ticks.push(); } return ( {ticks} ); } // ── SCENE 5 — OUTRO (tagline → brand signature) ───────────────────────────── function SceneOutro({ start, end }) { return ( {(lt, dur, t) => { // Beat A: tagline (0 → 2.7), Beat B: signature (2.6 → end) const aOut = vClamp(1 - (lt - 2.4) / 0.5, 0, 1); const aIn = vClamp(lt / 0.5, 0, 1); const aOp = E.easeInOutSine(Math.min(aIn, aOut)); const bIn = vClamp((lt - 2.6) / 0.6, 0, 1); const bOp = E.easeOutCubic(bIn); const bRise = (1 - bOp) * 26; const needleProg = vClamp((lt - 2.9) / 1.5, 0, 1); return (
{/* racing stripe */}
{/* Beat A — tagline */}
Für Branding
mit Emotionen.
{/* Beat B — signature */}
Mark Schönholzer
Senior Marketing Leader
); }} ); } Object.assign(window, { SceneLaut, SceneLeise, SceneKraftvoll, SceneRuhiger, SceneOutro, VC });