Communitygithub.com

opendirectory – 动态图形视频生成器

根据内容简报生成动态图形视频(MP4)。通过 Playwright 在无头 Chromium 中逐帧渲染多场景 HTML/CSS 动画,并用 FFmpeg 合成视频。默认 1080×1080,支持 16:9 (1920×1080) 和 9:16 (1080×1920)。提供 5 种样式预设。当用户说出“创建视频”、“动态图形”、“动画视频”、“制作 Reel”、“创建解说视频”、“动画信息图”或“短视频”时触发。

opendirectory – 动态图形视频生成器 是什么?

该技能是一个基于内容的动态图形视频生成工具,专为 AI 代理(如 Claude Code、Cursor、Codex)设计。它接收用户提供的内容简报(content_brief),自动解析成最多 6 个场景,并生成包含 HTML/CSS 动画的网页。随后,通过 Playwright 在无头 Chromium 浏览器中逐帧渲染该页面,并使用 FFmpeg 将这些帧合成为 MP4 视频文件。技能支持多种宽高比(1:1、16:9、9:16)和帧率(24、30、60),并内置了 5 种视觉风格预设(如 kinetic-dark、data-pulse)以及一个场景库,用于选择不同类型的卡片布局(如标题卡、统计揭示、列表、分屏)。其核心架构基于 `window.renderFrame(t)` 函数,该函数根据时间毫秒值直接计算每个场景的不透明度和变换,避免了 CSS `@keyframes` 在回退时可能被 Chromium 忽略的问题,从而保证了动画的确定性和帧精确度。该技能还包含严格的自我质量检查清单,确保视频输出无空白帧、文字可读且过渡流畅。

兼容平台✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/vid-motion-graphics

在你喜欢的 AI 中提问

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

文档

vid-motion-graphics

生成多场景动态图形视频(MP4)。通过 Playwright(Web 动画 API 帧定位)在无头 Chromium 中渲染 HTML/CSS 动画,然后用 FFmpeg 组装 PNG 帧。无需 React、无需 AI API、无需 Python——除了 graphic-gif 家族外,零新依赖。

仅使用 CDN 字体。HTML 中不引入外部库。


重要规则(每次生成前必读)

  1. 使用 window.renderFrame(t)——不要使用 CSS @keyframes 进行场景过渡。 CSS 动画的 currentTime 定位在 Chromium 中向后搜索时会被静默忽略。renderFrame 方案:纯 JS 函数根据毫秒值直接计算 opacity/transform。Playwright 每帧调用一次。确定性强、无竞态。
  2. 任何元素上均不得出现 animation-delay。 renderFrame 不需要它。如果你发现自己写了 animation-delay,停下来——你用的架构不对。
  3. window.__videoReady = true 必须放在 document.fonts.ready.then(...) 内部。 切勿同步设置——字体必须在 Playwright 捕获第 1 帧之前加载完毕,否则文本会显示为后备字体。
  4. 暴露 window.__stopPreview()。 浏览器的 rAF 预览循环与 Playwright 的 evaluate/screenshot 调用存在竞态。capture-frames.mjs 在帧循环开始前调用 __stopPreview()。务必包含此函数。
  5. 在场景边界检查中使用 t < startMs(而不是 <=)。t <= 0 会使第 0 帧的场景 1 变黑。正确的守卫是 if (t < startMs || t >= endMs) return hidden。
  6. Body 必须为精确像素尺寸。 宽度和高度是整数(如 1080px、1920px)。不得使用 %、vw/vh 或响应式单位。
  7. 任何时候不得有两个场景同时可见(除了 10% 的入场重叠)。所有场景在其 renderFrame 窗口之外必须 opacity: 0。
  8. 过渡仅使用 opacity。 不要使用 display 切换,不要使用 visibility——GPU 合成的不透明度可以做到帧精确。
  9. 切勿在聊天中转储 HTML。 保存到文件,仅显示摘要。
  10. 标题应陈述信息,而非主题。 如“Q4 达成目标的 3 个原因”,而不是“Q4 2024 绩效视频”。
  11. 生成任何 HTML 之前,先阅读 references/scene-library.md。 使用该文件中精确的 HTML 结构和 CSS 类名。

步骤 1:信息收集

必需项: content_brief

可选参数及其默认值:

参数默认值描述
content_brief—描述视频要传达的内容的文本(必需)
scenesauto场景数量(1–6)。Auto=根据简报自动推导
duration_per_scene3s每个场景的时长(秒,1–8s)
stylekinetic-darkkinetic-dark / editorial-light / data-pulse / bold-type / minimal-clean
aspect_ratio1:11:1 (1080×1080) / 16:9 (1920×1080) / 9:16 (1080×1920)
fps30每秒帧数(24、30 或 60)
musicnone背景音轨的音频文件路径(mp3/m4a/wav)
source—显示在最后一帧页脚的来源归属

如果缺少 content_brief,请精确询问:

“要创建视频,我需要一个内容简报——视频应该传达什么?

示例:'展示 Q4 收入增长 85% 的三个原因:新的企业交易、客户流失率降低、价格上涨。使用粗体数字。风格:data-pulse。'

可选:风格(默认:kinetic-dark)、宽高比(默认:1:1)、每个场景的秒数(默认:3秒)”

如果提供了 content_brief → 立即进入步骤 2。


步骤 2:内部架构(永不向用户展示)

1. 将简报解析为场景(最多 6 个):

  • 场景 1 = 吸引点或标题(始终如此)
  • 场景 2 到 N-1 = 支持性论点、指标或故事节拍
  • 场景 N = 行动号召或结束总结(如果多于 1 个场景,则始终如此)
  • 每个场景一个核心观点——如果简报有 7 个以上观点,合并最弱的那些

2. 阅读 references/scene-library.md——为每个场景选择场景类型:

  • 钩子/开场 → title-card
  • 单个指标 → stat-reveal
  • 2–4 个要点的列表 → bullet-list
  • 前后对比 / 两个值 → split-screen
  • 推荐 / 引用 → quote-card
  • 结尾 / 行动号召 → cta-card

3. 阅读 references/style-presets.md——为所选风格加载 CSS 令牌和动画个性。

4. 计算时间:

totalDuration = sceneCount × duration_per_scene  (秒)
totalFrames   = totalDuration × fps

每个场景占据总 @keyframes 范围的 (100 / sceneCount)%。

场景起始 %结束 %
10%(100/N)%
2(100/N)%(200/N)%
………
N((N-1)×100/N)%100%

在每个场景的范围内:

  • 进入:场景范围的前 10%
  • 保持:场景范围的 10% 到 85%
  • 退出:场景范围的 85% 到 100%

5. 确定像素尺寸:

  • 1:1 → W=1080, H=1080
  • 16:9 → W=1920, H=1080
  • 9:16 → W=1080, H=1920

步骤 3:HTML 生成

在编写任何代码之前,请阅读 references/scene-library.md 和 references/style-presets.md。

必需的 HTML 结构:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[来自样式预设的字体 CDN 链接]
<style>
:root {
  [来自样式预设的所有 CSS 令牌]
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
  width: [W]px; height: [H]px;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font-body);
  position: relative;
}

.scene {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px;
  opacity: 0;
  will-change: opacity, transform;
}
.scene-inner {
  width: 100%;
  max-width: 960px;
}

/* 来自 scene-library.md 的场景类型 CSS */
[在此粘贴场景类型 CSS]
</style>
</head>
<body>

<div class="scene scene-1">
  <div class="scene-inner">
    [来自 scene-library.md 模板的场景 1 HTML]
  </div>
</div>

[为每个场景重复]

<script>
window.__videoReady = false;
window.TOTAL_DURATION_MS = [totalDuration * 1000];

// ── 动画辅助函数 ─────────────────────────────────────────────────────────
function lerp(a, b, p) { return a + (b - a) * p; }
function clamp(v, lo, hi) { return Math.max(lo, Math.min(hi, v)); }
function easeOutCubic(t) { return 1 - Math.pow(1 - clamp(t, 0, 1), 3); }

function sceneState(t, startMs, endMs) {
  if (t < startMs || t >= endMs) return { opacity: 0, ty: 0 };
  const prog = (t - startMs) / (endMs - startMs);
  if (prog < 0.10) {
    const p = easeOutCubic(prog / 0.10);
    return { opacity: p, ty: lerp(24, 0, p) };
  }
  if (prog < 0.85) return { opacity: 1, ty: 0 };
  const p = (prog - 0.85) / 0.15;
  return { opacity: 1 - p, ty: lerp(0, -12, p) };
}

function applySceneState(el, state) {
  el.style.opacity = state.opacity;
  el.style.transform = state.ty !== 0 ? `translateY(${state.ty.toFixed(2)}px)` : '';
}

// ── 主渲染函数 —— Playwright 每帧调用一次 ────────────────────────────────
window.renderFrame = function(t) {
  // 场景 1:0ms – [D]ms
  applySceneState(document.querySelector('.scene-1'), sceneState(t, 0, [D]));
  // 场景 2:[D]ms – [2D]ms
  applySceneState(document.querySelector('.scene-2'), sceneState(t, [D], [2D]));
  // ... 为每个场景重复 ...
};

// ── 预览循环 —— 在帧捕获前由 Playwright 停止 ─────────────────────────────────
let __previewActive = false;
let __previewRafId = null;
window.__stopPreview = function() {
  __previewActive = false;
  if (__previewRafId !== null) { cancelAnimationFrame(__previewRafId); __previewRafId = null; }
};

document.fonts.ready.then(() => {
  window.renderFrame(0);
  window.__videoReady = true;
  __previewActive = true;
  const startTime = performance.now();
  function previewTick() {
    if (!__previewActive) return;
    const elapsed = performance.now() - startTime;
    if (elapsed < window.TOTAL_DURATION_MS) {
      window.renderFrame(elapsed);
      __previewRafId = requestAnimationFrame(previewTick);
    } else {
      window.renderFrame(window.TOTAL_DURATION_MS - 1);
      __previewActive = false;
    }
  }
  __previewRafId = requestAnimationFrame(previewTick);
});
</script>
</body>
</html>

设计质量规则:

  • 标题字号:不得小于 60px——文本必须能在移动端缩略图尺寸下阅读
  • 数字和统计数据:始终是屏幕上最大的元素(120–200px)
  • 显示字体的紧缩字间距:-0.02em 到 -0.04em
  • 每个场景一种强调色——不要将强调色分散到多个元素上
  • 暗色预设:分隔线 rgba(255,255,255,0.10),切勿使用实色
  • 亮色预设:分隔线 rgba(0,0,0,0.10),切勿使用实色
  • 每个使用 transform 的元素上都要有 transform-origin: center center
  • .scene 内边距:至少 80px——绝不让文本触及视口边缘

步骤 4:自我质量检查(在进入步骤 5 之前修复所有问题)

renderFrame 正确性:

  • window.renderFrame(t) 已定义——纯函数,无超出样式写入的副作用
  • 场景边界使用 t < startMs(而非 t <= startMs)——避免第 0 帧变黑
  • 场景过渡中零个 animation-delay 或 @keyframes 实例
  • 没有两个场景有重叠的 opacity: 1 窗口(除了 10% 的入场重叠)
  • 已暴露 window.__stopPreview(),并且预览 rAF 循环检查 __previewActive

就绪信号:

  • window.__videoReady = false 在 document.fonts.ready 之前声明
  • window.__videoReady = true 仅在 document.fonts.ready.then(...) 内部设置
  • window.renderFrame(0) 在 document.fonts.ready.then(...) 内部、设置 __videoReady = true 之前调用

布局:

  • html, body 使用精确像素尺寸([W]px、[H]px)
  • body 的宽度/高度上没有 %、vw、vh、rem 单位
  • html, body 上设置了 overflow: hidden
  • 所有场景 position: absolute; inset: 0

设计:

  • 所有颜色来自样式预设令牌——没有自由十六进制值
  • 所有字体来自样式预设——没有自由 font-family 字符串
  • 标题字号 ≥ 60px
  • 如果提供了 source 参数,则在最后一帧中包含来源信息

步骤 5:导出

根据简报内容确定 slug(kebab-case,≤30 字符):

mkdir -p chart/[slug]

保存 HTML:chart/[slug]/video.html

浏览器预览:

open chart/[slug]/video.html

运行导出(将 [skill-root] 替换为该技能目录的路径):

bash [skill-root]/scripts/export-video.sh \
  chart/[slug]/video.html \
  chart/[slug]/video.mp4 \
  --duration [totalDuration] \
  --fps [fps] \
  --width [W] \
  --height [H] \
  [--music path/to/audio.mp3]

该脚本在首次运行时安装 Playwright(约 200MB Chromium),捕获所有帧,然后使用 FFmpeg 组装 MP4。


步骤 6:输出摘要

## 视频:[来自简报的标题]
日期:[YYYY-MM-DD] | 场景数:[N] | 风格:[style] | 宽高比:[ratio]
时长:[N]秒 | FPS:[fps] | 帧数:[N]

文件
  源文件:   chart/[slug]/video.html
  输出文件: chart/[slug]/video.mp4
  大小:     [X] MB

检查清单
- [ ] 所有场景按顺序出现,无空白帧
- [ ] 文本在移动端缩略图尺寸下清晰可读
- [ ] 场景过渡流畅(无跳切)
- [ ] 最后一帧包含行动号召或结束信息
- [ ] 最后一帧包含来源归属(如果提供)

提示技巧(当用户请求指导时显示)

“提供一个内容简报——用要点列出每个场景应说的内容。”

“直接命名洞察。例如‘Q4 增长 85% 的 3 个理由’能让视频有主线。”

“如果你有偏好,可以提及风格:kinetic-dark(默认)、editorial-light、data-pulse、bold-type、minimal-clean。”

“指定针对平台的宽高比:1:1 用于 LinkedIn/Instagram 信息流,9:16 用于 Stories/Reels,16:9 用于 YouTube/演示。”

✅ 好的示例:“创建一个 9 秒的视频。Q4 收入达到 420 万美元(增长 85%)。驱动因素:企业交易、客户流失率 1.2%、价格上涨。行动号召:acme.com/q4。风格:data-pulse。宽高比:1:1。”

❌ 差的示例:“做一个关于我们公司的视频”

Individual skills in this repo

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

Varnan-Tech/opendirectory

Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.

Varnan-Tech/opendirectory

World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.

Varnan-Tech/opendirectory

Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.

Varnan-Tech/opendirectory

Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.

Varnan-Tech/opendirectory

Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.

Varnan-Tech/opendirectory

Give it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.

Varnan-Tech/opendirectory

Generate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).

Varnan-Tech/opendirectory

Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".

Varnan-Tech/opendirectory

Generates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.

Varnan-Tech/opendirectory

Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.

Varnan-Tech/opendirectory

Brutally honest developer-experience audit for a GitHub repo. Scores 10 DX dimensions (time-to-first-success, README clarity, visual proof, install, quick-start, docs, examples, community, trust, marketing), writes a shareable roast in the requested tone (brutal/honest/kind), produces a prioritized action plan ranked by impact × effort, and sketches an ideal README. Trigger when user says "roast my repo", "audit my README", "dx audit", "developer experience review", "score my GitHub project", "before launch checklist", or "make my repo shareable".

Varnan-Tech/opendirectory

Drafts and designs a complete HTML email newsletter from a topic or content brief. Outputs paste-ready HTML for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform. Includes subject line options and plain-text fallback. Trigger when a user says "write a newsletter", "draft an email newsletter", "create an HTML email", "design an email for my subscribers", or "write a newsletter about [topic]".

Varnan-Tech/opendirectory

Takes a GitHub PR URL or the current branch and writes a plain-English explanation of what it does and why, then posts it as a PR comment. Use when asked to explain a PR, summarize a pull request, write a plain-English description of a PR, add a summary comment to a PR, or understand what a PR changes. Trigger when a user says "explain this PR", "summarize this pull request", "what does this PR do", "add a comment explaining the PR", or shares a GitHub PR URL and asks what it does.

Varnan-Tech/opendirectory

Audit how often LLMs recommend your brand vs competitors and generate a GEO action plan.

Varnan-Tech/opendirectory

Takes a competitor's public GitHub repo URL, fetches their open issues via the GitHub REST API, filters noise locally, clusters issues into 6 demand categories, computes a demand score per issue and per cluster, and outputs a ranked demand gap report with a GTM messaging brief. Use when asked to scan a competitor's GitHub issues, find what their users are begging for, turn GitHub complaints into product positioning, identify competitor feature gaps, or generate messaging from real user demand. Trigger when a user says "scan competitor issues", "what are users asking for on X repo", "find demand gaps in Y", "turn GitHub issues into messaging", or "what should I build based on competitor complaints".

Varnan-Tech/opendirectory

Find recurring confusion in your repo's GitHub Discussions, rank it by urgency, and draft the actual docs fixes and content angles — with verbatim community quotes and source links as evidence.

Varnan-Tech/opendirectory

SEO keyword research workflow for blog generation using Google Trends data. Use when writing blog posts, planning content calendars, or optimizing articles for search engines. Finds breakout keywords, builds content structure, and generates SEO-optimized blog outlines targeting tech and developer audiences.

Varnan-Tech/opendirectory

Generates a professionally designed case study PDF for B2B SaaS sales and marketing. Supports 7 page layouts, 9 style presets, 1-4 page output. Trigger when user says "create a case study", "write a customer story", "make a case study PDF", "design a success story", "turn this customer win into a PDF".

Varnan-Tech/opendirectory

Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers".

Varnan-Tech/opendirectory

Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.

相关技能