mcpField
G
graphic-gif

graphic-gif

github.com/varnan-tech创意与媒体68743 次安装2 周前更新
代码仓库

关于 graphic-gif

用于制作动画 GIF 的技能,默认通过 CSS 动画生成,也可按明确要求使用 Kling 图像转视频流程。适合制作短篇视觉动效,并输出 HTML 源文件和 GIF。

主要功能

  1. 01通过 CSS 动画生成 GIF
  2. 02支持 Kling 图像转视频生成
  3. 03设置时长、帧率、风格和尺寸
  4. 04捕获动画帧并导出优化后的 GIF

适用场景

  1. 01制作社交媒体动画图形
  2. 02将动态文字或计数器制作为 GIF

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/varnan-tech/opendirectory --skill graphic-gif

安装后在 Claude Code 中输入/graphic-gif确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
evals/
evals.json
references/
animation-library.md
style-presets.md
scripts/
capture-and-encode.mjs
export-gif.sh

详细介绍

graphic-gif

根据 CSS 动画或 AI 图像转视频 API 生成循环动画 GIF。输出:animation.gif。

与其他所有输出静态 PNG 或 PDF 的 graphic- 技能不同,此技能输出动画 .gif。使用 Playwright 和 Web Animations API 逐帧捕获 CSS @keyframes 动画(选项 A,默认),或通过 Kling 使用 AI 图像转视频工作流(选项 B)。


关键规则(每次生成前阅读)

  1. 默认使用 css-animated。 除非用户明确要求,否则绝不使用 ai-generated。
  2. 画布为 800×800px 正方形。 所有 clamp() 值均按 800px 计算(1vw = 8px)。
  3. 使用单个独立 HTML 文件。 所有 CSS 都内联在 <style> 中。唯一外部依赖是字体 CDN <link>。
  4. 绝不在聊天中贴出 HTML。 保存到文件,只展示摘要。
  5. 使用 Web Animations API 跳转时间点来捕获帧。 不使用 setTimeout 循环,也不使用 animation-delay 技巧。
  6. 帧数必须精确: Math.floor(duration_seconds * fps) 帧。不得捕获 t=duration_ms 处的帧——它与 t=0 重复,会导致循环衔接处出现明显卡顿。
  7. 不要使用占位框。 仅使用 CSS 生成视觉效果。不要添加“图片放在这里”之类的元素。
  8. 调色板越简洁,文件越小。 使用:clean-slate、terminal、electric-burst、brutalist。
  9. 不要用 animation-delay 实现错开效果。 将错开时间写入 @keyframes 百分比中——逐帧跳转会处理时间。
  10. 编写 CSS 前先确定设计方向。 在写第一行代码前,确定基调、标志性元素、运动风格和令人难忘的细节。

第 1 步:收集需求

必需: prompt(内容描述和动态效果说明)

可选,使用默认值:

参数默认值选项
animation_typecss-animatedcss-animated / ai-generated
duration3.0秒
fps12帧/秒
looptruetrue / false
styleclean-slateclean-slate / terminal / electric-burst / brutalist
dimensions800x800WxH,单位为像素
optimizationbalancedquality / balanced / filesize

如果缺少 prompt 或动态效果说明,请原样询问:

"GIF 应该展示什么?请描述内容和动态效果(例如:'数字递增:73% 的买家在购买前会阅读 3 篇以上的内容。打字机效果,每次显示一个字符。风格:terminal。3 秒,12fps。')

关键设置(均为可选,括号内为默认值):

  • animation_type:css-animated(默认)或 ai-generated
  • duration:3.0 秒
  • fps:12
  • loop:true
  • style:clean-slate(选项:clean-slate / terminal / electric-burst / brutalist)
  • dimensions:800x800
  • optimization:balanced(选项:quality / balanced / filesize)"

如果必需信息齐全 → 直接跳到第 2 步。


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

对于 css-animated:

  1. 从以下类型中选择动画类型:fade-in、slide-in、typewriter、counter、pulse、loop-scroll
  2. 阅读 references/animation-library.md — 查找所选类型的完整 HTML/CSS 规范
  3. 阅读 references/style-presets.md — 加载所选样式的 CSS token 块
  4. 计算帧数:Math.floor(duration_seconds * fps) — 记下这个数字
  5. 确定设计方向:
决策推导依据
基调受众的情绪基调(机械 / 温暖 / 电感 / 专业)
标志性元素始终一致使用的一个视觉元素(光标闪烁、幽灵数字、扫描线叠层、强调色边框)
动效风格该类型的缓动曲线理念(弹簧 / 线性 / 步进 / 缓入缓出)
难忘细节观众会记住这个 GIF 的唯一亮点

对于 ai-generated:

  1. 生成基础静帧 HTML(适用于画布的海报式布局)
  2. 使用截图导出为 PNG
  3. 调用 Kling API:POST https://api.klingai.com/v1/videos/image2video,传入 image_url 和描述动效的 prompt
  4. 轮询任务完成状态
  5. 下载视频 → 使用 ffmpeg 转换为 GIF:
    # Two-pass palette for best color quality
    ffmpeg -i input.mp4 -vf "fps=12,scale=800:800:flags=lanczos,palettegen=stats_mode=diff" palette.png
    ffmpeg -i input.mp4 -i palette.png -vf "fps=12,scale=800:800:flags=lanczos,paletteuse=dither=bayer:bayer_scale=5" output.gif
    

步骤 3:HTML 生成(css-animated 路径)

生成前阅读 references/animation-library.md 和 references/style-presets.md。

画布基础样式 — 每个 GIF 都必须包含:

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

body {
  width: 800px;
  height: 800px;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font-body);
}

.canvas {
  width: 800px;
  height: 800px;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

动画规则:

  • 在所有动画元素上设置 animation-fill-mode: forwards(或 both)
  • 按类型设置计时函数:
    • typewriter → steps(N, end),其中 N = 字符总数
    • counter → linear
    • fade-in → cubic-bezier(0.22, 1, 0.36, 1)(缓出)
    • slide-in → cubic-bezier(0.34, 1.56, 0.64, 1)(弹簧式过冲)
    • pulse → ease-in-out,并设置 animation-iteration-count: infinite
    • loop-scroll → linear,并设置 animation-iteration-count: infinite
  • 对于单次动画(fade-in、slide-in、typewriter、counter):设置 animation-iteration-count: 1 — 循环由 GIF 层级处理
  • 不要使用 animation-delay — 通过 @keyframes 百分比实现错落效果

Typewriter 的 N 值计算: 统计每个字符,包括空格、标点和数字:

  • "73% of buyers" = 14 个字符 → steps(14, end)
  • "Hello, World!" = 13 个字符 → steps(13, end)

Counter CSS @property(counter 类型必需):

@property --num {
  syntax: '<integer>';
  inherits: false;
  initial-value: 0;
}
.counter {
  animation: countUp var(--duration) linear forwards;
  counter-reset: num var(--num);
}
.counter::after { content: counter(num); }
@keyframes countUp {
  from { --num: 0; }
  to   { --num: var(--target); }
}

Loop-scroll:必须重复内容:


<div class="ticker-track" style="--item-count: 4;">
  [item1][item2][item3][item4][item1][item2][item3][item4]
</div>

使用 translateX(0 → -50%),并设置 linear infinite。

设计质量规则(根据步骤 2 中确定的方向):

  • 标注的标志性元素必须出现在 CSS/HTML 中(不能只写在描述里)
  • 排版:展示文本与辅助文本之间的字重对比至少为 2:1(例如 700 与 400)
  • 背景:深色样式不要使用纯白色 #fff — 使用预设中的确切 --bg 值
  • 对于终端样式:使用 repeating-linear-gradient 添加 ::after 扫描线叠层,opacity: 0.03
  • 对于粗野主义样式:在关键元素上添加粗边框 4px solid #000 或 4px solid var(--accent)
  • 难忘细节:如果需要额外元素,就现在添加

Step 4:自检(在 Step 5 前修复所有问题)

画布:

  • body 和 .canvas 的尺寸均为 800×800px(或指定尺寸)
  • body 和 .canvas 均设置了 overflow: hidden
  • 没有元素超出画布边界

动画:

  • 任何地方都没有 animation-delay——交错效果通过 @keyframes 百分比实现
  • 所有动画都从 t=0 开始(Web Animations API 会从该位置开始定位)
  • 所有动画元素都设置了 animation-fill-mode: forwards 或 both
  • 单次动画:animation-iteration-count: 1
  • 无限动画(pulse、loop-scroll):animation-iteration-count: infinite

类型专项检查:

  • 打字机效果:steps(N, end) 中的 N = 文本字符串的准确字符数
  • 计数器:使用 syntax: '<integer>' 和 initial-value: 0 声明了 @property --num
  • 计数器:设置了 counter-reset: num var(--num) 和 ::after { content: counter(num) }
  • 循环滚动:HTML 中的内容恰好重复一次

设计:

  • 没有占位框
  • 已应用 references/style-presets.md 中的样式预设令牌——没有未归属的十六进制颜色
  • Step 2 中指定的标志性元素确实存在于 HTML/CSS 中
  • Step 2 中指定的令人难忘的细节确实已实现
  • 已为所选样式的字体添加 Font CDN <link>

Step 5:导出

根据提示词确定 slug(kebab-case,≤30 个字符)。创建输出目录:

mkdir -p [slug]

保存 HTML:

[slug]/animation.html

在浏览器中打开并快速检查视觉效果:

open [slug]/animation.html

运行导出脚本(将 [skill-root] 替换为此技能的实际路径):

bash [skill-root]/scripts/export-gif.sh \
  [slug]/animation.html \
  [slug]/animation.gif \
  --duration [duration] \
  --fps [fps] \
  [--no-loop if loop=false] \
  --optimization [optimization] \
  --width [W] \
  --height [H]

该脚本会:

  1. 在临时目录中安装 gifenc、sharp(或 jimp)和 playwright
  2. 如果 Chromium 尚未缓存,则下载 Chromium
  3. 运行 capture-and-encode.mjs——暂停动画、定位到每一帧、截屏并合成为 GIF
  4. 如果 gifsicle 可用,则运行优化流程
  5. 报告文件大小并打开结果

如果未找到导出脚本 [skill-root]/scripts/export-gif.sh,请检查技能安装时是否完整保留了 scripts/ 文件夹。


Step 6:输出摘要

成功导出后显示:

## GIF: [1-line description]
Date: [YYYY-MM-DD] | Style: [style] | Animation: [type] | [duration]s @ [fps]fps
Dimensions: [WxH] | Frames: [N] | Loop: [true/false]

Files
  Source:   [slug]/animation.html
  Output:   [slug]/animation.gif
  Size:     [X] KB

Checklist
- [ ] Preview loops cleanly at start/end point (no stutter)
- [ ] Text legible at intended display size
- [ ] File size appropriate: email <500KB / social <3MB

AI 生成路径(选项 B)

仅当明确指定 animation_type: ai-generated 时使用。

要求:

  • 环境中配置了 Kling API 密钥:KLING_API_KEY(每天 66 个免费点数,免费套餐无需信用卡)
  • 本地已安装 ffmpeg,用于将视频转换为 GIF

工作流:

  1. 生成与提示词相符的基础静帧 HTML(海报/图形风格,采用指定尺寸)
  2. 将静帧导出为 PNG:
    # Quick screenshot via Playwright
    node -e "
      const { chromium } = require('playwright');
      (async () => {
        const browser = await chromium.launch();
        const page = await browser.newPage({ viewport: { width: W, height: H } });
        await page.goto('file://[slug]/animation.html');
        await page.screenshot({ path: '[slug]/base-frame.png' });
        await browser.close();
      })();
    "
    
  3. 上传到 Kling 图生视频端点
  4. 使用 ffmpeg 的两遍调色板转换将结果转为 GIF
  5. 使用 gifsicle 优化

**Kling 不可用时:**改用 css-animated,并告知用户:“AI 生成需要 Kling API 密钥(KLING_API_KEY)。正在改用 css-animated。设置该密钥即可启用 AI 生成。”


提示词建议(用户寻求指导时显示)

“描述动作,而不仅仅是内容。‘数据逐个递增’比‘显示数据’更好。”

“保持简单以减小文件体积。使用 1–3 个动画元素和纯色背景。”

“考虑循环效果。动画从结束到开始应无缝衔接。”

“明确指定动画类型。typewriter 和 counter 最适合社交媒体内容。”

✅ 好:“创建一个动画 GIF,使用 css-animated 和打字机效果。文本:‘73% 的 B2B 买家在联系销售前会阅读 3 篇以上的内容。’逐个输入每个字符。样式:terminal。时长 3 秒,12fps,loop=true。”

❌ 不好:“制作一张关于营销技巧的动画 GIF”

评论

支持 Markdown