🎁 Get the FREE AI Skills Starter GuideSubscribe →
BytesAgainBytesAgain
🦀 ClawHub

SVG Animator

by @juliantsaiii

Generate animated videos from SVG frames using text LLM. Supports any subject (animals, humans, characters, scenes, abstract art), automatic duration calcula...

Versionv1.0.0
Downloads956
TERMINAL
clawhub install svg-animator

📖 About This Skill


name: svg-animator description: Generate animated videos from SVG frames using text LLM. Supports any subject (animals, humans, characters, scenes, abstract art), automatic duration calculation, and multi-scene story animations. Perfect替代 AI 视频生成 API,直接用文本模型生成 SVG 代码然后合成视频。

SVG Animator

用文本模型生成 SVG 代码,逐帧渲染后合成视频。完全不需要视频生成 API!

支持的场景

  • 动物:小狗奔跑、小猫跳跃、鱼儿游泳、鸟儿飞翔
  • 人物:走路、跑步、跳舞、工作场景
  • 场景:日出日落、云彩飘动、树叶落下、雨滴下落
  • 抽象:几何变换、颜色渐变、粒子效果
  • 故事:多场景连续动画(需要多段拼接)
  • 使用流程

    用户:生成一个"小猫伸懒腰"的动画
    ↓
    1. 理解需求 → 确定主题、动作、时长
    2. 设计帧序列 → 每帧的 SVG 代码
    3. 生成帧 → Node.js 生成 SVG → rsvg-convert 转 PNG
    4. 合成视频 → ffmpeg 合成 MP4/GIF
    5. 输出 → 返回文件路径或 nginx 链接
    

    时长计算规则

    | 需求 | 帧数 | 时长 | fps | |------|------|------|-----| | 简单动作(伸懒腰、眨眼) | 8-12帧 | 1秒 | 10 | | 常规动作(走路、跑步) | 16-24帧 | 2秒 | 12 | | 复杂动作(跳舞、翻滚) | 30-48帧 | 3-4秒 | 12 | | 短故事(2-3个场景) | 60-120帧 | 5-10秒 | 12 | | 长故事(5+场景) | 120+帧 | 10秒+ | 15 |

    动画原理

    周期性运动(正弦函数)

    // 帧索引 i,总帧数 totalFrames
    const t = (i / totalFrames) * Math.PI * 2;  // 0 → 2π 循环

    // 腿部摆动 const legOffset = Math.sin(t) * 40;

    // 尾巴摇动 const tailAngle = Math.sin(t * 2) * 25;

    // 身体上下颠簸 const bodyY = Math.sin(t) * 5;

    多元素协调

    // 腿、尾巴、身体用同一个 t,但幅度不同
    const legPhase = t;           // 腿部周期
    const tailPhase = t * 2;      // 尾巴周期快一倍
    const bodyPhase = t;          // 身体与腿同步

    // 组合使用 legOffset = Math.sin(legPhase) * 40; tailAngle = Math.sin(tailPhase) * 25; bodyY = Math.sin(bodyPhase) * 5;

    帧生成代码模板

    const fs = require('fs');
    const { execSync } = require('child_process');

    const frames = 24; // 根据时长需求调整 const size = 400;

    for (let i = 0; i < frames; i++) { const t = (i / frames) * Math.PI * 2; // 计算运动参数 const legOffset = Math.sin(t) * 40; const tailAngle = Math.sin(t * 2) * 25; // ... 更多参数

    const svg = ;

    fs.writeFileSync(/tmp/frames/frame_${String(i).padStart(2, '0')}.svg, svg); }

    // 转 PNG execSync('rsvg-convert frame_*.svg -o frame_%02d.png');

    // 合成视频 execSync('ffmpeg -y -framerate 12 -i frame_%02d.png -c:v mpeg4 -q:v 2 output.mp4');

    常用动画参数

    走路/奔跑

    const runCycle = {
      legSwing: Math.sin(t) * 40,      // 腿摆动幅度
      bodyBob: Math.sin(t * 2) * 5,   // 身体颠簸
      tailWag: Math.sin(t * 2) * 30,  // 尾巴摇
      armSwing: Math.sin(t) * 25      // 手臂摆动
    };
    

    飞行

    const flyCycle = {
      wingUp: Math.sin(t) * -45,      // 翅膀上扬
      wingDown: Math.sin(t) * 45,     // 翅膀下落
      bodyTilt: Math.sin(t) * 10,     // 身体倾斜
      glide: Math.sin(t) * 20         // 滑翔高度变化
    };
    

    跳跃

    const jumpCycle = {
      yOffset: -Math.abs(Math.sin(t)) * 100,  // 垂直位移
      legTuck: Math.abs(Math.sin(t)) * 30,   // 收腿
      armUp: Math.abs(Math.sin(t)) * -30      // 举手
    };
    

    摇摆/晃动

    const swayCycle = {
      rotation: Math.sin(t) * 15,     // 整体摇摆角度
      xOffset: Math.sin(t) * 10,     // 水平位移
      wave: Math.sin(t * 3) * 5      // 轻微晃动
    };
    

    场景动画示例

    日出

    // 太阳从地平线升起
    const progress = i / frames;
    const sunY = size * 0.8 - progress * size * 0.6;  // 从下往上
    const skyGrad = rgb(${255 * progress}, ${200 * progress}, ${100 + 155 * progress});
    

    云飘动

    const cloudX = (i / frames) * size * 1.5;  // 从左往右
    // 云朵透明度随位置变化
    const opacity = 1 - (cloudX / size) * 0.5;
    

    雨滴下落

    // 多滴雨
    for (let drop = 0; drop < 10; drop++) {
      const startFrame = (frames / 10) * drop;
      const dropPos = ((i - startFrame) / frames) * size;
      // 绘制雨滴在 dropPos 位置
    }
    

    多场景故事动画

    当用户需要"讲一个故事"时,生成多个场景然后拼接:

    // 场景1:小猫醒来(12帧)
    // 场景2:伸懒腰(12帧)  
    // 场景3:玩耍(24帧)
    // 场景4:吃饭(16帧)
    // 场景5:睡觉(12帧)

    // 分别生成后用 ffmpeg 拼接 const scenes = ['scene1.mp4', 'scene2.mp4', 'scene3.mp4']; const concatList = scenes.map(s => file '${s}').join('\n'); fs.writeFileSync('/tmp/concat.txt', concatList); execSync(ffmpeg -y -f concat -safe 0 -i /tmp/concat.txt -c copy story.mp4);

    完整工作流

    Step 1: 分析需求

    "生成一个小狗追蝴蝶的故事动画"
    

    分解:

  • 主题:小狗 + 蝴蝶
  • 动作:追逐(小狗跑 + 蝴蝶飞)
  • 场景:草地、天空
  • 时长:5-8秒(3个场景)
  • Step 2: 设计场景

    1. 场景1(0-3秒):小狗看到蝴蝶 - 小狗站立,尾巴摇 - 蝴蝶飞过 2. 场景2(3-6秒):追逐 - 小狗奔跑(24帧循环) - 蝴蝶飞舞(上下移动) 3. 场景3(6-8秒):抓到/没抓到 - 小狗停下 - 蝴蝶继续飞 / 小狗开心

    Step 3: 生成代码

    # 创建帧目录
    mkdir -p /tmp/animation_frames

    用 Node.js 生成 SVG(根据设计的场景)

    node generate_story.js

    转换 PNG

    rsvg-convert /tmp/animation_frames/*.svg -o /tmp/animation_frames/frame_%04d.png

    合成视频

    ffmpeg -y -framerate 12 -i /tmp/animation_frames/frame_%04d.png \ -c:v mpeg4 -q:v 2 /tmp/story.mp4

    Step 4: 提供下载

    复制到 nginx 目录或直接发送文件路径

    注意事项

    1. ffmpeg 必须安装 - dnf install ffmpegapt install ffmpeg 2. rsvg-convert 必须 - 用于 SVG → PNG 3. 帧数不要太多 - 超过 200 帧可能很慢 4. 复杂故事分场景 - 不要把所有动作放一帧里 5. 背景简洁 - 复杂背景会影响性能

    辅助脚本

    使用 scripts/animate.js 简化流程:

    # 基本动画
    node scripts/animate.js --theme "dog running" --frames 24 --output /tmp/dog.mp4

    自定义时长(秒)

    node scripts/animate.js --theme "cat stretching" --duration 2 --output /tmp/cat.mp4

    多场景故事

    node scripts/animate.js --story "小兔子的一天" --scenes 5 --output /tmp/rabbit_day.mp4

    输出格式

  • MP4:适合分享,文件小
  • GIF:适合嵌入网页/文档
  • 链接:部署到 nginx 通过 http 提供
  • # 转 GIF
    ffmpeg -i input.mp4 -vf "fps=12,scale=480:-1:flags=lanczos" output.gif