Communitygithub.com

Karthic1981/hoodini-ai-agents-skills.gitni-ai-agents-skills

构建一个高级的电影级着陆页,具有鼠标擦洗视频英雄区和品牌驱动的叙事弧线部分。每当用户提供英雄视频和产品/主题/品牌时使用。

hoodini-ai-agents-skills.gitni-ai-agents-skills 是什么?

这个技能用于构建一个高级的电影级着陆页,其核心特性是鼠标驱动的视频擦洗效果:英雄视频作为固定背景覆盖整个页面,鼠标左右移动会擦洗视频时间轴,使内容响应光标位置。在英雄区下方,包含4-5个完全不透明的部分,每个部分拥有独立的品牌标识(颜色、排版重点、布局模式),引导观众走过一个五拍叙事弧(例如:渴望→喜悦→怀旧→沉思→行动)。该技能支持多种语言(包括RTL和LTR,如希伯来语、英语、阿拉伯语等)和任何主题(食品、科技、时尚、SaaS等)。工作流程包括资产准备(使用ffmpeg将每个帧重新编码为关键帧以实现流畅擦洗)、项目搭建(基于React + TypeScript + Tailwind CSS)、组件实现(鼠标擦洗效果、滚动揭秘、导航)以及详细的验证步骤。参考实现来自一个以色列RTL网站,展示了该技能的实际效果。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Karthic1981/hoodini-ai-agents-skills.gitni-ai-agents-skills/tree/HEAD/skills/cinematic-scrub-landing

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

带有鼠标擦洗视频和玻璃标题面板的英雄区
黄色
奶油色
深色
红色

文档

电影感擦洗着陆页 — 黄金模板

构建一个高级的品牌感知着陆页,英雄视频响应鼠标移动,页面其余部分引导观众走过五个节拍的叙事弧。用户提供视频,可选地提供Logo + 产品照片 + 品牌背景——此技能负责调色板提取、排版选择、RTL/LTR、项目搭建、全关键帧视频重新编码、鼠标擦洗效果、部分库和验证。

为什么存在这个技能

参考实现位于 https://github.com/hoodini/bamba —— 一个以色列RTL网站,针对小吃“במבה”,其中婴儿视频跟踪光标跨越整个页面,下方4个不同的部分(亮黄色食谱、奶油色怀旧相册、深色沉思定价、红色行动结尾)引导观众走过 渴望→喜悦→怀旧→沉思→行动。

带有鼠标擦洗视频和玻璃标题面板的英雄区

此技能中的每条规则都是从该构建中提取的。硬规则部分 中的要点都是来之不易的——它们覆盖了通用的“好代码”默认值。


部分画廊(你正在构建的内容)

英雄区保持顶部。在其下方,从库中选择4个部分,按叙事弧顺序排列。每个部分完全不透明(无视频透出)并拥有自己的品牌标识:

节拍类型参考
1 — 渴望英雄区(鼠标擦洗视频)英雄区
2 — 喜悦太阳 — 明亮的主色调强调渐变,浮动主题SVG,巨大幽灵排版,统计卡片黄色
3 — 怀旧相册 — 奶油色纸张,点状微图案,宝丽来弯曲布局,真实产品照片奶油色
4 — 沉思烘烤 — 深色带径向强调发光,三个定价卡片,每个具有不同的视觉处理深色
5 — 行动信号 — 全出血强烈强调色(红/橙/绿),巨大标题+CTA,玻璃容器面板红色

对于技术/SaaS品牌,根据需要交换部分类型(见下面的部分库)——但始终以信号部分结束。


如何使用这个技能

  1. 将资产放入 一个干净的工作目录:

    • 英雄视频(任何容器 — .mp4、.mov、.webm)
    • Logo(强烈推荐SVG;PNG带透明度可接受)
    • 1-3张产品/主题图片(JPG/PNG,透明理想)
  2. 与用户确认(简要 — 提出默认值,然后继续):

    • 产品名称 + 元标语
    • 语言代码(驱动RTL/LTR + 字体选择)
    • 品牌背景 — 时代、受众、情感核心、调色板感觉
    • 可选:明确的调色板十六进制值、叙事弧节拍
  3. 按顺序执行以下工作流程。 所有阶段都是强制性的。不要跳过ffmpeg重新编码——那是使擦洗感觉流畅的魔法。

  4. 在报告完成之前进行验证。 阶段9有12项检查。运行所有。


输入 — 从用户处收集这些

PRODUCT_NAME: "<例如  במבה / Bamba / Hope the Cheetah / Acme CRM>"
TAGLINE: "<元消息 — 例如 'it's not a snack, it's lifelong memories'>"
LANGUAGE: "<he | en | ar | es | fr | ja | ...>"
IS_RTL: "<true | false>"                                   # he/ar/fa = true; 其他均为false
HERO_VIDEO_FILE: "<工作目录中的确切文件名 — 例如 baby2.mp4>"
LOGO_FILE: "<确切文件名 — 如果没有则留空>"
PRODUCT_IMAGE_FILE: "<确切文件名 — 如果没有则留空>"
BRAND_CONTEXT: |
  <2-4句话:它唤起的时代、目标受众、情感核心、
  视觉特性(温暖/冷静/有趣/严肃)。驱动调色板+主题。>
PALETTE: "<可选 — 如果覆盖则用逗号分隔的十六进制值>"
NARRATIVE_ARC: "<可选 — 5个情感节拍;如果空白则AI建议>"

完整文本模板(包含相同的YAML块和提示正文)位于 references/GOLDEN_PROMPT.md —— 当您没有直接技能运行时访问时,将其粘贴到Claude中并填充YAML。


阶段0 — 规划设计(在编码前输出≤200字的简报)

在编写任何代码之前,输出:

  1. 提取的5色调色板:background(最深墨水色)、cream(暖色米白文本 — 绝不使用 #FFFFFF)、accent(主要品牌颜色)、accent2(次要品牌颜色)、support(第三色调)。如果未提供 PALETTE,则从Logo+产品图片中提取。调色板必须在内部协调 — 要么全暖色,要么全冷色,绝不可混合。暖色品牌(食品、自然、怀旧、动物)→ 不含蓝色、蓝绿色、薄荷色、青色。冷色品牌(科技、金融、医疗、科幻)→ 不含暖色调,除了一个小强调色。

  2. 排版三位一体(显示/正文/手写强调色)针对该语言:

    • he:Rubik(显示) + Assistant(正文) + Suez One(强调色)
    • en:Anton(显示) + Inter(正文) + Caveat(强调色)
    • ar:Cairo(显示) + Tajawal(正文) + Reem Kufi(强调色)
    • es / fr / it / de:Anton 或 Bebas Neue(显示) + Inter(正文) + Caveat(强调色)
    • ja:Noto Sans JP 权重 900(显示) + Noto Sans JP(正文) + Yusei Magic(强调色)
    • 其他语言:选择三种匹配该文字系统的Google字体,具有相同的 display-black / body-clean / handwritten-script 角色。
  3. 叙事弧 — 5个情感节拍,映射到 BRAND_CONTEXT。将每个节拍与部分库中的节拍匹配。

然后执行 — 不需要要求确认。


阶段1 — 资产准备(魔法步骤)

1a. 验证ffmpeg

which ffmpeg     # 或:PowerShell上使用 Get-Command ffmpeg

如果缺失,停止并告诉用户安装(brew install ffmpeg / Windows:http://ffmpeg.org)。

1b. 重新编码英雄视频,使每一帧都是关键帧

浏览器只能直接跳转到关键帧 — 标准视频大约每250帧有一个关键帧,这使得鼠标擦洗严重卡顿。单条命令就是高级与业余之间的差别:

ffmpeg -y -i <HERO_VIDEO_FILE> -g 1 -keyint_min 1 -c:v libx264 -preset slow -crf 20 -pix_fmt yuv420p -an hero.mp4

验证输出:hero.mp4 应在5-50 MB之间。如果 > 50 MB,重新运行 -crf 25;如果 > 80 MB,使用 -crf 28。剥离音频(-an) — 英雄视频是无声的。

1c. 复制Logo和产品图片

cp <LOGO_FILE>           public/logo.<ext>
cp <PRODUCT_IMAGE_FILE>  public/product.<ext>   # 如果提供

阶段2 — 搭建项目框架

npm create vite@latest site -- --template react-ts
cd site
npm install
npm install lucide-react
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p
mkdir -p public
mv ../hero.mp4 public/hero.mp4
# 同时将Logo+产品图片移动到public/

阶段3 — Tailwind配置

完全替换 tailwind.config.js。使用提取的调色板和语言合适的字体:

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: {
        background: '<墨水色/深色>',
        cream:      '<暖色米白 — 绝不使用 #FFFFFF>',
        accent:     '<主要品牌颜色>',
        accent2:    '<次要>',
        support:    '<第三色调>',
      },
      fontFamily: {
        sans:    ['<正文字体>',         'system-ui', 'sans-serif'],
        display: ['<显示字体>',      'sans-serif'],
        accent:  ['"<手写字体>"', 'cursive'],
      },
    },
  },
  plugins: [],
}

阶段4 — index.html

完全替换。遵守 IS_RTL。始终包含指向Logo的favicon链接:

<!DOCTYPE html>
<html lang="<LANGUAGE>" dir="<rtl|ltr>">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/logo.svg" />
    <link rel="apple-touch-icon" href="/logo.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="<所选三种字体的Google Fonts URL>" rel="stylesheet">
    <title><产品名称> — <标语></title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

阶段5 — index.css(设计系统)

完全替换。下面的每个实用类都是承重的。名称假设之前提取的暖色调色板;对于冷色品牌,将阴影色调中的“黄色”/“红色”提及替换为实际强调色。

必须包含:

  • html { scroll-behavior: smooth; } + section[id] { scroll-margin-top: 90px; } 以便锚定的部分不会落在固定导航下方。
  • body 背景 = background 颜色(视频失败时的回退)。光标 = crosshair。默认字体 = 正文无衬线字体。
  • .liquid-glass / .liquid-glass-strong — 背景模糊+饱和度+内发光边框+蒙版渐变边缘高光。强变体使用以 accent 着色的内发光。
  • .glass-pill — 紧凑的圆角药丸形状,具有相同的玻璃效果,用于导航项和小徽章。
  • .cta-primary — 品牌CTA:linear-gradient(135deg, accent-light, accent, accent-shade) + 强调色发光阴影,在悬停时增强 + translateY(-1px) 抬起效果。
  • .brand-mark — 小型正方形/圆形,用于没有提供SVG时的小Logo标记。
  • .grid-bg — 微妙的1px网格,带有径向淡出蒙版,用于暗色部分下方。
  • .reveal / .revealed — IntersectionObserver滚动揭示:opacity 0 → 1 + translateY 28 → 0 在0.9秒内,使用 cubic-bezier(0.16, 1, 0.3, 1)。
  • .scrim-top / .scrim-bottom — 仅用于英雄区的渐变覆盖层。
  • 按感觉而非颜色命名的各部分背景:
    • .sun-section — 明亮的主色调强调渐变 + 微妙的点状纹理(“喜悦/打开包装”节拍)。
    • .album-section — 暖色米白纸张,径向强调色调 + 点状微图案,边缘蒙版淡出。
    • .roast-section — 深色,带有在相对角部的径向强调色 + 强调色2发光 + 蒙版网格纹理。
    • .signal-section — 全出血强烈强调色(通常是红/橙/绿色)用于行动终章。
  • .polaroid — 白色卡片,内边距 14px 14px 44px 14px,柔和的分层阴影,悬停时抬起至 translateY(-6px) rotate(0)。.polaroid-tape = 黄色/强调色胶带条,绝对定位在顶部居中,旋转-4°,带有虚线侧边提示。
  • .stamp — 强调色虚线边框药丸形状,大写,字母间距 0.18em。
  • .ribbon — 定价/热门徽章,带有 clip-path 三角形底部,深色投影。
  • .highlight-circle — 手绘感觉的椭圆,通过 ::after 绘制:围绕一个内联 <span> 的旋转3px强调色边框。在大型标题中最重要的单词周围使用它(每个标题最多一个)。
  • 装饰性主题滤镜:.peanut-svg / .<主题>-svg 带有 drop-shadow。
  • 遵守 prefers-reduced-motion: reduce — 在媒体查询内停用揭示动画和平滑滚动。

阶段6 — App.tsx 架构

架构不容商量。第一次就做对:

6a. 导入

import { useEffect, useRef, useState } from 'react';
import {
  Menu, X, ArrowLeft, ArrowRight, ArrowDown, ArrowUp, MousePointer2,
  // …加上4-8个品牌主题图标(Heart, Sparkles, Cookie, PawPrint, Cpu, Leaf, …)
} from 'lucide-react';

6b. 在App.tsx内定义的可复用组件

  • useReveal<T>() — IntersectionObserver钩子,返回一个ref;在第一次相交时添加 revealed 类(阈值0.15)。
  • GlassCard — 包装器,带有揭示钩子,可选的 strong 属性,接受className。
  • Motif — 一个装饰性SVG组件,主题与 BRAND_CONTEXT 相关(食品用花生,动物用爪子,科技用电路,自然用叶子,饮料用液滴,能源用闪电)。在每个暗/亮部分中以低不透明度浮动在3-6个位置。
  • ScrollToTopButton — 固定定位,RTL中为 bottom-6 left-6 / LTR中为 bottom-6 right-6。当 window.scrollY > window.innerHeight * 0.6 时出现。平滑滚动到顶部。简短的语言合适标签("לראש" / "Top" / "أعلى" / "返回顶部")。

6c. 鼠标擦洗效果(核心)

const videoRef = useRef<HTMLVideoElement>(null);
const stateRef = useRef({ targetTime: 0, isSeeking: false });

useEffect(() => {
  const video = videoRef.current;
  if (!video) return;

  const handleLoaded = () => {
    const mid = video.duration / 2;
    video.currentTime = mid;
    stateRef.current.targetTime = mid;
  };

  const handleSeeked = () => {
    const s = stateRef.current;
    s.isSeeking = false;
    if (Math.abs(s.targetTime - video.currentTime) > 0.01) {
      s.isSeeking = true;
      video.currentTime = s.targetTime;
    }
  };

  const handleMouseMove = (e: MouseEvent) => {
    const s = stateRef.current;
    const d = video.duration;
    if (!d || isNaN(d)) return;
    const normalized = e.clientX / window.innerWidth;
    // 如果主体相对于光标“向后”移动且感觉不对,可以选择
    // 使用 `1 - (e.clientX / window.innerWidth)` 代替 — 先询问用户。
    s.targetTime = Math.max(0, Math.min(d, normalized * d));
    if (!s.isSeeking) { s.isSeeking = true; video.currentTime = s.targetTime; }
  };

  video.addEventListener('loadedmetadata', handleLoaded);
  video.addEventListener('seeked', handleSeeked);
  window.addEventListener('mousemove', handleMouseMove);
  return () => {
    video.removeEventListener('loadedmetadata', handleLoaded);
    video.removeEventListener('seeked', handleSeeked);
    window.removeEventListener('mousemove', handleMouseMove);
  };
}, []);

isSeeking 守卫是关键的 — 没有它,鼠标移动触发频率超过浏览器解码能力,导致seek队列溢出和可见卡顿。

6d. 可点击的滚动监视导航

const navItems: { label: string; target: string }[] = [
  { label: '<演示>',     target: 'top'     },
  { label: '<食谱>',   target: 'recipe'   },
  { label: '<相册>',   target: 'album'    },
  { label: '<定价>',   target: 'pricing'  },
  { label: '<现在获取>', target: 'cta'     },
];

导航通过滚动监视高亮当前部分。使用 IntersectionObserver 监视每个部分,并相应更新活动导航项。


阶段7 — 部分库(在英雄区之后选择4-5个)

每个部分封装为一个组件。英雄区固定,其余部分可滚动。每个部分都应包含 useReveal 以实现滚动入动画。

7a. 英雄区(必需)

  • 全屏视口,视频作为固定背景,覆盖整个页面
  • 视频元素绝对定位,object-fit: cover,z-index: -1
  • 覆盖层:顶部和底部渐变遮罩(.scrim-top / .scrim-bottom)
  • 覆盖层内容:Logo + 标题 + 标语 + 可选的下滚动提示
  • 标题显示在 .liquid-glass 面板中,大号 font-display 文本

7b. 太阳部分 — 喜悦/主要特征

  • 明亮的渐变色背景,带有细微点状纹理
  • 大型统计卡片或特征网格,每个卡片带有 GlassCard 包装
  • 巨大的幽灵排版元素作为装饰背景
  • 浮动主题SVG(Motif)

7c. 相册部分 — 故事/过程

  • 暖色米白纸张背景,带有点状微图案
  • 宝丽来样式卡片网格(.polaroid),包含真实产品图片
  • 时间线或步骤视觉元素
  • 手写字体用于情感化副标题(font-accent)

7d. 烘烤部分 — 对比/定价

  • 深色背景,带有来自相对角的径向强调和强调色2发光
  • 三个定价/选项卡片,每个具有不同的视觉处理:
    • 标准:干净、简单的卡片
    • 特色/热门:突出强调色,带有 .ribbon 徽章
    • 高级:深色玻璃变体,带有附加元素
  • .stamp 元素用于标签

7e. 信号部分 — 行动呼吁

  • 全出血强烈强调色背景(红/橙/绿)
  • 大型标题,可能带有 .highlight-circle
  • 主要的CTA按钮(.cta-primary)
  • 玻璃容器面板(.liquid-glass)包含次要信息

阶段8 — 硬规则(优先级高于任何矛盾的最佳实践)

  1. 绝不使用 #FFFFFF — 所有浅色背景/文本都应使用从调色板中选择的暖色米白色或微妙的浅色调。
  2. 文本文本必须足够对比 — 任何身体文本至少达到WCAG AA(4.5:1对比度)。标题可以更宽松(3:1)。
  3. 一个副标题,一个手写强调字 — 每个部分最多一个手写字体单词/短语。过度使用会稀释效果。
  4. 每个部分完全独立 — 没有从英雄区视频透出的部分。每个部分有 background-color 或渐变覆盖整个视口。
  5. 叙述弧必须连贯 — 5个节拍必须有情感进展。不能随机排序。
  6. 无默认动画 — 所有动画通过 useReveal 触发。英雄区擦洗是唯一持续运动。
  7. 全球字体是必需的 — 始终通过Google Fonts加载三种字体。不使用系统字体回退作为主要字体。
  8. 全部内联 — 无外部CSS文件 — 所有样式通过Tailwind实用类 + index.css完成。无单独的 .module.css 文件。
  9. ffmpeg re-encode 是强制性的 — 不要跳过或替代。没有它,鼠标擦洗感觉混乱。
  10. isSeeking 守卫必须存在于鼠标擦洗效果中 — 没有它,体验会卡顿。
  11. 始终包含一个可用CTA — 信号部分必须有一个用户可以点击的按钮或链接。
  12. 在平板/手机上优雅降级 — 视频擦洗变成触摸滑动擦洗,或简化为静态帧 + 视频上的覆盖播放/暂停按钮。

阶段9 — 验证清单(在报告完成前运行所有)

运行此完整清单。每一项都必须通过:

  • V1 — npm run dev 启动无错误
  • V2 — 英雄视频加载并全屏显示(发生在 loadedmetadata 之后)
  • V3 — 鼠标左右移动擦洗视频(isSeeking 在工作 — 检查控制台是否快速连续seek)
  • V4 — 在初始擦洗后视频不会重置为第一帧(handleLoaded 正确设置中间点)
  • V5 — 所有4-5个部分可见,每个有独立的背景色/渐变
  • V6 — 滚动时部分淡入(revealed 类在相交时应用)
  • V7 — 导航点击滚动到正确的部分
  • V8 — 活动导航项随滚动更新
  • V9 — 所有链接、CTA和交互元素工作
  • V10 — 在RTL语言中,布局适当地镜像(dir="rtl")
  • V11 — 文本内容与提供的品牌语境匹配(无默认的Lorem Ipsum)
  • V12 — hero.mp4 文件存在于 public/ 中,由ffmpeg编码(不是原始上传文件)

附录A — 参考实现

完整项目在 hoodini/bamba 可用。它是针对以色列品牌במבה的RTL网站,但模式适用于任何品牌。

关于此技能结构的关键文件:

  • src/App.tsx — 主要组件树
  • src/index.css — 所有样式,包括部分特定的
  • public/hero.mp4 — 重新编码的英雄视频
  • src/components/ — 包含可复用部分组件

附录B — 常见品牌术语映射

品牌类型节拍1(渴望)节拍2(喜悦)节拍3(怀旧)节拍4(沉思)节拍5(行动)
SaaS“问题”“解决方案”“流程”“定价”“注册”
食品/饮料“第一口”“食谱”“起源”“比较”“现在购买”
时尚“风格困境”“系列亮点”“档案”“定价”“购物”
非营利/野生动物“问题”“我们做什么”“成功故事”“如何帮助”“捐赠”
音乐/娱乐“等待”“歌曲/专辑”“灵感”“巡演”“现在收听”

使用此映射将5个叙述节拍转化为具体的部分标题和内容,与品牌语境匹配。

Individual skills in this repo

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

Karthic1981/hoodini-ai-agents-skills.gitni-ai-agents-skills

Build a scroll-driven cinematic landing page from a short video. The user provides a 5–15 second video (often AI-generated); this skill extracts every frame at HD JPEG quality, then produces a single-hero HTML page where the user's scroll gesture scrubs the frames in place (the page itself never scrolls) and 5 dramatic text overlays crossfade in/out — Google Anton headlines, Caveat handwritten accents, locked body, virtual scroll. Use this skill whenever the user wants to "turn this video into a landing page", "make a scroll-scrub landing page", "build a parallax hero from this clip", "add a new landing page to the parasites showcase", "do the same as github/lion/hope for this new video", or any variant that pairs a short clip with dramatic scroll-triggered storytelling. Trigger even if the user only says "use my video for a landing page" — that is this skill.

Karthic1981/hoodini-ai-agents-skills.gitni-ai-agents-skills

Turn any video into a cinematic scroll-driven landing page — Apple-style hero where scrolling progresses the visible frame through the video. Use when the user provides a video file and asks for "a landing page from this video", "scroll-frame website", "Apple-style scroll site", "hero that scrubs the video", "like the GitHub Copilot landing", or any equivalent. Extracts N evenly-spaced frames via ffmpeg, builds a self-contained HTML page with a sticky hero + JS scroll listener that swaps the visible frame as you scroll, plus headline, sections and CTA below. For YUV.AI projects, applies the yuv-design-system skill in Neon mode (pink/cyan/white, default for YUV.AI web) — Decks (purple/yellow) is reserved for slides only. For generic / non-YUV.AI projects, picks an appropriate palette per the source video. Output is one folder with `index.html` and a `frames/` directory — drop on any static host.

相关技能