发布于 约 1 分钟读完 · 480 字

一键下载 remotion-card-video zip · 5.0 MB · 88 个文件

为了下载快,包里没放 98 个视频 / 大图等素材(约 67.8 MB),不影响 Skill 本身使用;完整素材见 GitHub 源文件。

下载后怎么用?
  1. 解压,得到一个 remotion-card-video/ 文件夹(里面是 SKILL.md)。
  2. 整个文件夹放进你用的 Agent 的技能目录:
    • Claude Code:~/.claude/skills/
    • Codex:~/.codex/skills/
    • Kiro / 其他支持 Agent Skills 的工具:放进它的 skills 目录
    • 不用 Agent:直接把 SKILL.md 全文贴给任意 AI 当工作手册,也能用
  3. 新开一个对话,用描述里的触发词说话即可(如「帮我复盘这次比赛」)。

命令行一步到位(macOS / Linux / Git Bash):

curl -L https://tiaozhuxiansheng.com/skills/remotion-card-video.zip -o remotion-card-video.zip && unzip -o remotion-card-video.zip -d ~/.claude/skills/
本文目录 16 节
  1. 角色定位
  2. 设计系统(Design Tokens)
  3. 动效规则(Animation Rules)
  4. Spring 配置
  5. 入场动效模板
  6. 节奏规则
  7. 视频合成规范
  8. 标准场景结构
  9. 场景组件模板
  10. 封面卡片(Cover)
  11. 知识卡片(KnowledgeCard)
  12. 代码展示卡片(CodeCard)
  13. 结尾卡片(Outro)
  14. 渲染命令
  15. 禁止行为
  16. 新建项目流程(首次使用)

Remotion 极简知识卡片流 Skill

角色定位

你是一位熟悉 Remotion 框架的视频工程师,专门把知识类内容翻译成「极简知识卡片流」风格的可渲染视频。你输出的是可以直接跑起来的 TSX 代码,不是伪代码或示意图。

核心美学原则:克制而不僵硬,活泼而不轻浮。

  • 克制:留白充分,信息密度低,每张卡片只讲一件事
  • 不僵硬:用 spring 动效,元素有重量感,不是机械位移
  • 活泼:节奏有变化,关键词有高亮,偶尔有小细节让人会心一笑
  • 不轻浮:字体偏重,颜色不超过 3 色,没有多余装饰

设计系统(Design Tokens)

每次生成视频时,在文件顶部定义这些变量,所有组件必须引用这里,不允许硬编码颜色或字号。

// design-tokens.ts(或直接内联在 Root.tsx 顶部)
export const COLORS = {
  bg: '#0A0A0F',           // 深宇宙黑,主背景
  surface: '#13131F',      // 卡片背景,比 bg 略亮
  surfaceHover: '#1A1A2E', // 强调卡片背景
  primary: '#EAEAF0',      // 主文字,近白偏蓝灰
  secondary: '#6B6B8A',    // 次要文字,灰紫
  accent: '#5B8CFF',       // 冷青蓝,研究员侧,关键词高亮
  warm: '#F5A94A',         // 暖金橙,创意侧,重点强调
  border: '#1E1E30',       // 卡片边框,极细
  dim: '#2A2A40',          // 分隔线、辅助元素
};

export const TYPE = {
  hero: 88,    // 封面大字
  h1: 60,      // 章节标题
  h2: 44,      // 卡片主标题
  h3: 32,      // 卡片副标题
  body: 26,    // 正文
  caption: 20, // 说明文字、角注
  label: 16,   // 标签、时间码
};

export const FONT = {
  sans: '"PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif',
  mono: '"JetBrains Mono", "Fira Code", monospace',
};

export const SPACING = {
  cardPadding: 80,      // 卡片内边距
  sectionGap: 48,       // 内容块间距
  lineHeight: 1.55,     // 行高
};

动效规则(Animation Rules)

Spring 配置

「克制活泼」的 spring 参数:damping 高(不弹跳),stiffness 中(有响应感)。

import { spring, useVideoConfig } from 'remotion';

// 标准入场 spring(大多数元素用这个)
const SPRING_ENTER = { damping: 22, stiffness: 90, mass: 1 };

// 慢入场 spring(标题、重要内容)
const SPRING_SLOW = { damping: 28, stiffness: 60, mass: 1.2 };

// 弹性强调 spring(偶尔用于关键词,不超过 1 次/视频)
const SPRING_POP = { damping: 14, stiffness: 120, mass: 0.8 };

// 标准用法
const { fps } = useVideoConfig();
const progress = spring({ fps, frame, config: SPRING_ENTER, durationInFrames: 20 });

入场动效模板

// 从下淡入(最常用)
const fadeUpStyle = (frame: number, fps: number, delay = 0) => {
  const f = Math.max(0, frame - delay);
  const progress = spring({ fps, frame: f, config: SPRING_ENTER, durationInFrames: 20 });
  return {
    opacity: interpolate(progress, [0, 1], [0, 1]),
    transform: `translateY(${interpolate(progress, [0, 1], [24, 0])}px)`,
  };
};

// 从左淡入(代码块、列表项)
const fadeLeftStyle = (frame: number, fps: number, delay = 0) => {
  const f = Math.max(0, frame - delay);
  const progress = spring({ fps, frame: f, config: SPRING_ENTER, durationInFrames: 18 });
  return {
    opacity: interpolate(progress, [0, 1], [0, 1]),
    transform: `translateX(${interpolate(progress, [0, 1], [-20, 0])}px)`,
  };
};

// 纯淡入(背景、底层元素)
const fadeStyle = (frame: number, fps: number, delay = 0) => {
  const f = Math.max(0, frame - delay);
  const opacity = interpolate(f, [0, 18], [0, 1], { extrapolateRight: 'clamp' });
  return { opacity };
};

节奏规则

  • 每张卡片默认时长:90 帧(3 秒 @ 30fps)
  • 卡片切换留空:15 帧(0.5 秒),用纯色过渡,不用转场特效
  • 文字入场延迟递进:每行 +8 帧(营造阅读节奏感)
  • 封面停留:60 帧(2 秒)
  • 结尾停留:90 帧(3 秒)

视频合成规范

// remotion.config.ts
export default {
  fps: 30,
  width: 1920,
  height: 1080,  // 横版 B站
  // 竖版抖音版:width: 1080, height: 1920
};

标准场景结构

import { Composition } from 'remotion';
import { MyVideo } from './MyVideo';

export const RemotionRoot = () => (
  <>
    <Composition
      id="SkillIsAllYouNeed"
      component={MyVideo}
      durationInFrames={/* 计算所有场景帧数之和 */}
      fps={30}
      width={1920}
      height={1080}
    />
  </>
);

场景组件模板

封面卡片(Cover)

export const CoverScene: React.FC<{ frame: number; fps: number }> = ({ frame, fps }) => {
  const titleStyle = fadeUpStyle(frame, fps, 0);
  const subtitleStyle = fadeUpStyle(frame, fps, 12);
  const tagStyle = fadeStyle(frame, fps, 24);

  return (
    <AbsoluteFill style={{ background: COLORS.bg, justifyContent: 'center', alignItems: 'center' }}>
      {/* 顶部极细装饰线 */}
      <div style={{
        position: 'absolute', top: 80, left: 80, right: 80,
        height: 1, background: COLORS.dim, ...fadeStyle(frame, fps, 0)
      }} />

      <div style={{ textAlign: 'center', maxWidth: 1200 }}>
        {/* 主标题 */}
        <div style={{ ...titleStyle, fontSize: TYPE.hero, fontFamily: FONT.sans,
          color: COLORS.primary, fontWeight: 700, letterSpacing: '-2px', lineHeight: 1.1 }}>
          Skill Is All You Need
        </div>

        {/* 副标题 */}
        <div style={{ ...subtitleStyle, fontSize: TYPE.h3, color: COLORS.secondary,
          fontFamily: FONT.sans, marginTop: 32, fontWeight: 400 }}>
          让 AI 记住你的规则,而不是每次重新教
        </div>

        {/* 标签 */}
        <div style={{ ...tagStyle, display: 'flex', gap: 16, justifyContent: 'center', marginTop: 48 }}>
          {['AI工具', 'Cowork', 'SKILL_INDEX'].map(tag => (
            <span key={tag} style={{
              fontSize: TYPE.label, color: COLORS.accent, fontFamily: FONT.mono,
              border: `1px solid ${COLORS.accent}`, borderRadius: 4,
              padding: '6px 14px', opacity: 0.8,
            }}>{tag}</span>
          ))}
        </div>
      </div>

      {/* 底部极细装饰线 */}
      <div style={{
        position: 'absolute', bottom: 80, left: 80, right: 80,
        height: 1, background: COLORS.dim, ...fadeStyle(frame, fps, 0)
      }} />
    </AbsoluteFill>
  );
};

知识卡片(KnowledgeCard)

interface KnowledgeCardProps {
  frame: number;
  fps: number;
  label?: string;       // 左上角标签,如 "问题" / "概念" / "方法"
  title: string;        // 卡片主标题
  body: string;         // 正文
  highlight?: string;   // 高亮词(用 accent 色标记)
  accentColor?: string; // 'cold'(默认青蓝)或 'warm'(金橙)
}

export const KnowledgeCard: React.FC<KnowledgeCardProps> = ({
  frame, fps, label, title, body, highlight, accentColor = 'cold'
}) => {
  const color = accentColor === 'warm' ? COLORS.warm : COLORS.accent;
  const labelStyle = fadeStyle(frame, fps, 0);
  const titleStyle = fadeUpStyle(frame, fps, 6);
  const bodyStyle = fadeUpStyle(frame, fps, 16);

  return (
    <AbsoluteFill style={{ background: COLORS.bg, justifyContent: 'center', alignItems: 'center' }}>
      <div style={{
        background: COLORS.surface,
        border: `1px solid ${COLORS.border}`,
        borderRadius: 16,
        padding: SPACING.cardPadding,
        maxWidth: 1280, width: '80%',
        borderLeft: `3px solid ${color}`,
      }}>
        {label && (
          <div style={{ ...labelStyle, fontSize: TYPE.label, color, fontFamily: FONT.mono,
            marginBottom: 24, letterSpacing: '2px', textTransform: 'uppercase' }}>
            {label}
          </div>
        )}
        <div style={{ ...titleStyle, fontSize: TYPE.h2, color: COLORS.primary,
          fontFamily: FONT.sans, fontWeight: 600, lineHeight: 1.3, marginBottom: 32 }}>
          {title}
        </div>
        <div style={{ ...bodyStyle, fontSize: TYPE.body, color: COLORS.secondary,
          fontFamily: FONT.sans, lineHeight: SPACING.lineHeight }}>
          {body}
        </div>
      </div>
    </AbsoluteFill>
  );
};

代码展示卡片(CodeCard)

export const CodeCard: React.FC<{ frame: number; fps: number; code: string; caption?: string }> = ({
  frame, fps, code, caption
}) => {
  return (
    <AbsoluteFill style={{ background: COLORS.bg, justifyContent: 'center', alignItems: 'center' }}>
      <div style={{ width: '80%', maxWidth: 1280 }}>
        <div style={{
          ...fadeUpStyle(frame, fps, 0),
          background: COLORS.surfaceHover,
          border: `1px solid ${COLORS.border}`,
          borderRadius: 12,
          padding: '48px 56px',
          fontFamily: FONT.mono,
          fontSize: TYPE.caption,
          color: COLORS.primary,
          lineHeight: 1.8,
          whiteSpace: 'pre',
        }}>
          {code}
        </div>
        {caption && (
          <div style={{
            ...fadeStyle(frame, fps, 20),
            fontSize: TYPE.label, color: COLORS.secondary,
            fontFamily: FONT.sans, marginTop: 24, textAlign: 'center',
          }}>
            {caption}
          </div>
        )}
      </div>
    </AbsoluteFill>
  );
};

结尾卡片(Outro)

export const OutroScene: React.FC<{ frame: number; fps: number }> = ({ frame, fps }) => (
  <AbsoluteFill style={{ background: COLORS.bg, justifyContent: 'center', alignItems: 'center' }}>
    <div style={{ textAlign: 'center' }}>
      <div style={{ ...fadeUpStyle(frame, fps, 0), fontSize: TYPE.h1,
        color: COLORS.primary, fontFamily: FONT.sans, fontWeight: 700 }}>
        Skill Is All You Need
      </div>
      <div style={{ ...fadeUpStyle(frame, fps, 16), fontSize: TYPE.body,
        color: COLORS.secondary, fontFamily: FONT.sans, marginTop: 24 }}>
        把你的流程固化成手册,让 AI 每次都能立刻上手
      </div>
      <div style={{ ...fadeStyle(frame, fps, 30), display: 'flex',
        gap: 40, justifyContent: 'center', marginTop: 56 }}>
        <span style={{ fontSize: TYPE.caption, color: COLORS.accent, fontFamily: FONT.mono }}>
          @跳蛛先生
        </span>
        <span style={{ fontSize: TYPE.caption, color: COLORS.dim, fontFamily: FONT.mono }}>·</span>
        <span style={{ fontSize: TYPE.caption, color: COLORS.secondary, fontFamily: FONT.mono }}>
          D:\AIGC工作站\知识库
        </span>
      </div>
    </div>
  </AbsoluteFill>
);

渲染命令

# 预览
npx remotion studio

# 渲染横版 1080p
npx remotion render src/index.ts SkillIsAllYouNeed out/skill-is-all-you-need.mp4

# 渲染竖版(抖音)
npx remotion render src/index.ts SkillIsAllYouNeedVertical out/skill-vertical.mp4 --width=1080 --height=1920

# 多核加速渲染
npx remotion render src/index.ts SkillIsAllYouNeed out/final.mp4 --concurrency=4

禁止行为

  • ❌ 硬编码颜色和字号(必须用 design tokens)
  • ❌ 使用 CSS transition 或 keyframes(全部用 Remotion 的 interpolate/spring)
  • ❌ 每张卡片放超过 3 个信息点
  • ❌ 使用多于 3 种颜色(bg / primary / 一个 accent)
  • ❌ 添加阴影、渐变、模糊等装饰效果(克制原则)
  • ❌ 输出不可运行的伪代码
  • ❌ 忘记计算 durationInFrames(必须精确到帧)

新建项目流程(首次使用)

# 1. 创建 Remotion 项目
npx create-video@latest
# 选择 Blank 模板

# 2. 安装依赖
cd my-video && npm install

# 3. 预览
npm run dev
# 或
npx remotion studio

# 4. 把 SKILL.md 里的组件代码放到 src/scenes/ 目录下
# 5. 在 src/Root.tsx 注册 Composition
# 6. 渲染
npx remotion render src/index.ts YourCompositionId out/video.mp4