Communitygithub.com

Biznomad/agent-skills

Biznomad - Build Apple-grade video scroll-animated websites and scrollytelling experiences using GSAP ScrollTrigger, Lenis smooth scroll, Canvas image sequences, ALL-I encoded HTML5 video scrubbing, and sticky HUD overlays.

agent-skills 是什麼?

agent-skills is a Claude Code agent skill that biznomad - Build Apple-grade video scroll-animated websites and scrollytelling experiences using GSAP ScrollTrigger, Lenis smooth scroll, Canvas image sequences, ALL-I encoded HTML5 video scrubbing, and sticky HUD overlays.

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Biznomad/agent-skills/tree/HEAD/video-scroll-website

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Biznomad - Video Scroll Animated Websites (Apple-Grade Scrollytelling)

This skill provides complete architectural patterns, FFmpeg compression pipelines, and production JS/CSS code for building high-performance, video scroll-animated websites matching Apple, Stripe, Lusion, and Awwwards Site-of-the-Day standards.


Industry Research & Architectural Breakdown

When building scroll-driven video experiences, top tech and design agencies select from three primary rendering strategies:

StrategyIndustry ReferenceBest ForProsCons
Canvas Image SequenceApple (MacBook, AirPods, iPhone)Precision scrub, zero lag, frame perfection60–120fps butter-smooth, works on all mobile GPUsRequires frame preloading (20–60MB array)
ALL-I Encoded HTML5 VideoStripe, Nike, TeslaQuick setup, low bandwidth single fileSingle MP4 download, fast initializationRequires low keyframe distance (-g 1)
WebGL Texture ShaderLusion, Active Theory, Cuberto3D depth distortion, liquid glass effectsUltra-creative, lighting & refraction controlHigher GPU overhead, shader complexity

1. Video Preparation & FFmpeg Encoding Pipeline

To achieve instant, smooth frame scrubbing without stutter, the video MUST be encoded with a keyframe distance of 1 (every frame is an Intra-frame / Keyframe).

Option A: Prepare Video for HTML5 Video Scrubbing (ALL-I Encoding)

Run this FFmpeg command to generate an ultra-fast scrubbing MP4:

ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -preset slow -crf 18 -g 1 -keyint_min 1 -an -movflags +faststart output_scrub.mp4

Option B: Prepare Frame Sequence for Canvas Scrubbing (Apple Style)

Extract compressed 1080p WebP or JPEG frames:

mkdir -p frames
ffmpeg -i input.mp4 -vf "scale=1920:1080" -q:v 85 frames/frame_%04d.jpg
# Or for WebP (smaller file size):
ffmpeg -i input.mp4 -vf "scale=1920:1080" -c:v libwebp -quality 85 frames/frame_%04d.webp

2. Technical Stack Configuration

  • Smooth Scrolling Engine: @studio-freight/lenis or Lenis (eliminates jitter and provides momentum scroll)
  • Animation Driver: GSAP 3.12+ with ScrollTrigger
  • Rendering Layer: <canvas> with 2D Context or <video> with currentTime sync
  • Typography & HUD: Glassmorphic fixed overlay cards synced to frame timeline triggers

3. Production Architecture: Apple-Style Canvas Sequence (Recommended)

Below is the production-ready implementation of an Apple-style Canvas frame scroll sequence with preloader, smooth Lenis scroll, and floating scrollytelling copy layers.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Apple-Style Video Scroll Showcase</title>

<!-- Fonts & GSAP + Lenis CDNs -->
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lenis.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>

<style>
  :root {
    --bg: #000000;
    --paper: #f5f5f7;
    --dim: #86868b;
    --accent: #2997ff;
    --accent-glow: rgba(41, 151, 255, 0.35);
    --panel: rgba(22, 22, 23, 0.75);
    --line: rgba(255, 255, 255, 0.12);
  }

  * { box-sizing: border-box; margin: 0; padding: 0; }
  body {
    background: var(--bg);
    color: var(--paper);
    font-family: "Inter", system-ui, -apple-system, sans-serif;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
  }

  /* Preloader */
  #preloader {
    position: fixed;
    inset: 0;
    z-index: 999;
    background: #000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    transition: opacity 0.6s ease, visibility 0.6s ease;
  }
  #preloader.done { opacity: 0; visibility: hidden; }
  .loader-bar {
    width: 200px;
    height: 3px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 999px;
    overflow: hidden;
  }
  .loader-fill {
    height: 100%;
    width: 0%;
    background: var(--accent);
    transition: width 0.1s linear;
  }

  /* Sticky Scroll Canvas Stage */
  .scroll-stage {
    position: relative;
    height: 400vh; /* Determines length of scroll interaction */
  }
  .sticky-viewport {
    position: sticky;
    top: 0;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  canvas#scrollCanvas {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  /* Floating Scrollytelling Overlay Panels */
  .hud-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 10;
  }
  .hud-card {
    position: absolute;
    max-width: 460px;
    background: var(--panel);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line);
    border-radius: 20px;
    padding: 32px;
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.5s ease, transform 0.5s ease;
  }
  .hud-card.active {
    opacity: 1;
    transform: translateY(0);
  }
  .hud-eyebrow {
    font-family: "JetBrains Mono", monospace;
    color: var(--accent);
    font-size: 12px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    font-weight: 700;
    margin-bottom: 8px;
  }
  .hud-title {
    font-size: 32px;
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.1;
    margin-bottom: 12px;
  }
  .hud-desc {
    color: var(--dim);
    font-size: 15px;
    line-height: 1.6;
  }

  /* Individual HUD Positions */
  .hud-1 { top: 15%; left: 8%; }
  .hud-2 { top: 35%; right: 8%; }
  .hud-3 { bottom: 15%; left: 8%; }

  /* End Section */
  .outro-sec {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    background: #08080a;
    border-top: 1px solid var(--line);
    padding: 80px 24px;
  }
  .outro-title {
    font-size: clamp(40px, 6vw, 84px);
    font-weight: 900;
    letter-spacing: -0.04em;
    margin-bottom: 24px;
  }
  .btn-cta {
    display: inline-block;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    padding: 16px 36px;
    border-radius: 999px;
    text-decoration: none;
    box-shadow: 0 10px 30px var(--accent-glow);
    transition: transform 0.2s;
  }
  .btn-cta:hover { transform: scale(1.05); }
</style>
</head>
<body>

<!-- Preloader -->
<div id="preloader">
  <div style="font-weight:700;font-size:14px;letter-spacing:0.1em">LOADING EXPERIENCE</div>
  <div class="loader-bar"><div class="loader-fill" id="loaderFill"></div></div>
</div>

<!-- Scroll Video Container -->
<div class="scroll-stage" id="scrollStage">
  <div class="sticky-viewport">
    <canvas id="scrollCanvas"></canvas>

    <!-- Scrollytelling HUD Overlays -->
    <div class="hud-overlay">
      <div class="hud-card hud-1" id="hud1">
        <div class="hud-eyebrow">01 / ARCHITECTURE</div>
        <h2 class="hud-title">Precision Engineered.</h2>
        <p class="hud-desc">Every frame calculated in real-time. Unmatched visual velocity and fluid responsiveness.</p>
      </div>

      <div class="hud-card hud-2" id="hud2">
        <div class="hud-eyebrow">02 / TELEMETRY</div>
        <h2 class="hud-title">Real-Time Data Flow.</h2>
        <p class="hud-desc">Sub-millisecond synchronization between user scroll input and canvas presentation.</p>
      </div>

      <div class="hud-card hud-3" id="hud3">
        <div class="hud-eyebrow">03 / PERFORMANCE</div>
        <h2 class="hud-title">120 FPS Mastery.</h2>
        <p class="hud-desc">GPU accelerated canvas rendering with zero frame drop or scroll stuttering.</p>
      </div>
    </div>
  </div>
</div>

<section class="outro-sec">
  <div>
    <h1 class="outro-title">Ready to Launch.</h1>
    <a href="#" class="btn-cta">EXPERIENCE THE FUTURE →</a>
  </div>
</section>

<script>
document.addEventListener('DOMContentLoaded', () => {
  // 1. Initialize Lenis Smooth Scroll
  const lenis = new Lenis({
    duration: 1.2,
    easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
    smoothWheel: true
  });

  function raf(time) {
    lenis.raf(time);
    requestAnimationFrame(raf);
  }
  requestAnimationFrame(raf);

  // Sync Lenis with GSAP ScrollTrigger
  lenis.on('scroll', ScrollTrigger.update);
  gsap.ticker.add((time) => lenis.raf(time * 1000));
  gsap.ticker.lagSmoothing(0);

  // 2. Setup Canvas & Image Preloader
  const canvas = document.getElementById('scrollCanvas');
  const ctx = canvas.getContext('2d');
  const loaderFill = document.getElementById('loaderFill');
  const preloader = document.getElementById('preloader');

  const totalFrames = 120; // Number of extracted frames
  const images = [];
  const airbnb = { frame: 0 };

  // Frame URL generator (Replace with your relative path)
  const currentFrame = (index) => `./frames/frame_${(index + 1).toString().padStart(4, '0')}.jpg`;

  let loadedCount = 0;
  for (let i = 0; i < totalFrames; i++) {
    const img = new Image();
    img.src = currentFrame(i);
    img.onload = () => {
      loadedCount++;
      loaderFill.style.width = `${(loadedCount / totalFrames) * 100}%`;
      if (loadedCount === totalFrames) {
        preloader.classList.add('done');
        renderCanvas();
      }
    };
    images.push(img);
  }

  // Handle High-DPI Retina Displays
  function resizeCanvas() {
    const dpr = window.devicePixelRatio || 1;
    canvas.width = window.innerWidth * dpr;
    canvas.height = window.innerHeight * dpr;
    ctx.scale(dpr, dpr);
    renderCanvas();
  }
  window.addEventListener('resize', resizeCanvas);

  function renderCanvas() {
    if (!images[airbnb.frame]) return;
    const img = images[airbnb.frame];
    const w = window.innerWidth;
    const h = window.innerHeight;

    // Cover Fit Math
    const imgRatio = img.width / img.height;
    const canvasRatio = w / h;
    let drawW, drawH, offsetX, offsetY;

    if (canvasRatio > imgRatio) {
      drawW = w;
      drawH = w / imgRatio;
      offsetX = 0;
      offsetY = (h - drawH) / 2;
    } else {
      drawW = h * imgRatio;
      drawH = h;
      offsetX = (w - drawW) / 2;
      offsetY = 0;
    }

    ctx.clearRect(0, 0, w, h);
    ctx.drawImage(img, offsetX, offsetY, drawW, drawH);
  }

  // Initial Canvas Resize
  resizeCanvas();

  // 3. GSAP ScrollTrigger Sequence
  gsap.to(airbnb, {
    frame: totalFrames - 1,
    snap: "frame",
    ease: "none",
    scrollTrigger: {
      trigger: "#scrollStage",
      start: "top top",
      end: "bottom bottom",
      scrub: 0.5,
      onUpdate: () => renderCanvas()
    }
  });

  // 4. Scrollytelling HUD Overlays Triggers
  function setupHudTrigger(id, startPct, endPct) {
    ScrollTrigger.create({
      trigger: "#scrollStage",
      start: `${startPct}% top`,
      end: `${endPct}% top`,
      onEnter: () => document.getElementById(id).classList.add('active'),
      onLeave: () => document.getElementById(id).classList.remove('active'),
      onEnterBack: () => document.getElementById(id).classList.add('active'),
      onLeaveBack: () => document.getElementById(id).classList.remove('active')
    });
  }

  setupHudTrigger('hud1', 10, 30);
  setupHudTrigger('hud2', 35, 60);
  setupHudTrigger('hud3', 65, 90);
});
</script>

</body>
</html>

4. Alternative Architecture: Direct HTML5 Video Scrubbing

For projects using a single compressed .mp4 video with Intra-frame encoding (-g 1):

const video = document.getElementById('scrubVideo');
video.pause();

// Ensure metadata is loaded for duration
video.onloadedmetadata = function() {
  gsap.to(video, {
    currentTime: video.duration,
    ease: "none",
    scrollTrigger: {
      trigger: "#videoStage",
      start: "top top",
      end: "bottom bottom",
      scrub: 0.3
    }
  });
};

5. Golden Rules for Apple-Grade Quality

  1. Intra-frame Keyframes (-g 1): Mandatory for HTML5 video scrub, otherwise scrub stutters on keyframe seeking intervals.
  2. Device Pixel Ratio (DPR): Always scale canvas resolution by window.devicePixelRatio for razor-sharp Retina output.
  3. Aspect Ratio Cover Math: Calculate offsetX and offsetY on canvas resize so frames maintain full-bleed object-fit cover.
  4. Lenis Scroll Interpolation: Never omit smooth scroll inertia (Lenis). Pure native wheel events create discrete steps that degrade video scrubbing.
  5. Mobile Performance Fallback: On low-power mobile devices (matchMedia('(prefers-reduced-motion: reduce)') or low bandwidth), offer automatic video playback or static poster frames instead of heavy scrub calculations.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Biznomad/agent-skills

Landing page quality assessment for paid advertising campaigns. Evaluates message match, page speed, mobile experience, trust signals, form optimization, and conversion rate potential. Use when user says "landing page", "post-click experience", "landing page audit", "conversion rate", or "landing page optimization".

Biznomad/agent-skills

TikTok Ads deep analysis covering creative quality, tracking, bidding, campaign structure, and TikTok Shop. Evaluates 25 checks with emphasis on creative-first strategy, safe zone compliance, and Smart+ campaigns. Use when user says "TikTok Ads", "TikTok marketing", "TikTok Shop", "Spark Ads", "Smart+", or "TikTok campaign".

Biznomad/agent-skills

YouTube Ads specific analysis covering campaign types, creative quality, audience targeting, and measurement. Evaluates video ad performance across skippable, non-skippable, bumper, Shorts, and Demand Gen formats. Use when user says "YouTube Ads", "video ads", "pre-roll", "bumper ads", "YouTube campaign", or "Shorts ads".

Biznomad/agent-skills

Help users get promoted at work. Use when someone is preparing for a promotion conversation, building their case for advancement, trying to understand what's blocking their promotion, or figuring out how to get to the next level in their career.

Biznomad/agent-skills

CSS animation adapter patterns for HyperFrames. Use when authoring CSS keyframes, animation-delay based timing, animation-fill-mode, animation-play-state, or CSS-only motion that HyperFrames must seek deterministically during preview and rendering.

Biznomad/agent-skills

Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.

Biznomad/agent-skills

Read-only queue dashboard for workspace-aware ship. Shows which VERSION slots are currently claimed by open PRs, which sibling Conductor workspaces have WIP work likely to ship soon, and what slot /ship would pick next. No mutations — just a snapshot. Use when asked to "landing report", "what's in the queue", "show me open PRs", or "which version do I claim next". (gstack)

Biznomad/agent-skills

HyperFrames CLI dev loop — `npx hyperframes` for scaffolding (init), validation (lint, inspect), preview, render, and environment troubleshooting (doctor, browser, info, upgrade). Use when running any of these commands or troubleshooting the HyperFrames build/render environment. For asset preprocessing commands (`tts`, `transcribe`, `remove-background`), invoke the `hyperframes-media` skill instead.

Biznomad/agent-skills

Asset preprocessing for HyperFrames compositions — text-to-speech narration (Kokoro), audio/video transcription (Whisper), and background removal for transparent overlays (u2net). Use when generating voiceover from text, transcribing speech for captions, removing the background from a video or image to use as a transparent overlay, choosing a TTS voice or whisper model, or chaining these (TTS → transcribe → captions). Each command downloads its own model on first run.

Biznomad/agent-skills

Install and wire registry blocks and components into HyperFrames compositions. Use when running hyperframes add, installing a block or component, wiring an installed item into index.html, or working with hyperframes.json. Covers the add command, install locations, block sub-composition wiring, component snippet merging, and registry discovery.

Biznomad/agent-skills

Create video compositions, animations, title cards, overlays, captions, voiceovers, audio-reactive visuals, and scene transitions in HyperFrames HTML. Use when asked to build any HTML-based video content, add captions or subtitles synced to audio, generate text-to-speech narration, create audio-reactive animation (beat sync, glow, pulse driven by music), add animated text highlighting (marker sweeps, hand-drawn circles, burst lines, scribble, sketchout), or add transitions between scenes (crossfades, wipes, reveals, shader transitions). Covers composition authoring, timing, media, and the full video production workflow. For dev-loop CLI commands (init, lint, inspect, preview, render) see the hyperframes-cli skill; for asset preprocessing commands (tts, transcribe, remove-background) see the hyperframes-media skill.

Biznomad/agent-skills

Still-to-video conversion guide: model selection, motion prompting, and camera movement. Covers Wan 2.5 i2v, Seedance, Fabric, Grok Video with when to use each. Use for: animating images, creating video from stills, adding motion, product animations. Triggers: image to video, i2v, animate image, still to video, add motion to image, image animation, photo to video, animate still, wan i2v, image2video, bring image to life, animate photo, motion from image

Biznomad/agent-skills

>- The Landing Page Audit skill performs comprehensive evaluations of post-click experiences, combining technical performance analysis with conversion rate optimization (CRO) assessment.

Biznomad/agent-skills

Write high-converting landing page copy using proven frameworks like PAS (Problem-Agitate-Solution), AIDA, and StoryBrand. Creates headlines, value propositions, CTAs, and full page sections optimized for conversion. Use when users need landing page copy, sales page content, or marketing website text.

Biznomad/agent-skills

Optimize landing pages for higher conversion rates using proven frameworks and design patterns. Use when designing, reviewing, or improving landing pages, hero sections, pricing pages, CTAs, or when the user asks about conversion optimization.

Biznomad/agent-skills

Read-only queue dashboard for workspace-aware ship. (gstack)

Biznomad/agent-skills

Building promotion cases, brag documents, tracking wins, and self-advocacy for career advancement. Use when preparing for promotions, documenting accomplishments, or building your case for advancement.

Biznomad/agent-skills

Best practices for Remotion - Video creation in React

Biznomad/agent-skills

Translate an existing Remotion (React-based) video composition into a HyperFrames HTML composition. Use ONLY when the user explicitly asks to port, convert, migrate, translate, or rewrite a Remotion composition as HyperFrames (e.g. "port my Remotion project to HyperFrames"). Do NOT use when (a) authoring a NEW HyperFrames composition (even if A/B-testing a Remotion video); (b) Remotion is mentioned in passing; (c) Remotion code is shared as reference, not for translation; (d) the user wants "the same video as my Remotion one" without explicitly asking to migrate the source — treat as a fresh HyperFrames build. When in doubt, default to the `hyperframes` skill. Detects unsupported patterns (useState, useEffect side effects, async calculateMetadata, third-party React component libraries, `@remotion/lambda`) and recommends the runtime interop escape hatch instead of a lossy translation.

Biznomad/agent-skills

Produce programmable videos with Remotion using scene planning, asset orchestration, and validation gates for automated, brand-consistent video content.

相關技能