generative-illustration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Generative Illustration

生成式插画

Make expressive, concept-driven pieces by combining AI-generated illustration assets with code-driven motion. This is the lane designers call 动态平面 / motion graphic design — built the agent-native way: an AI makes the visuals, code gives them life and meaning.
通过将 AI 生成的插画素材 与 代码驱动的动态效果 结合,创作富有表现力、由概念驱动的作品。这就是设计师所称的 动态平面 / 动态图形设计领域——以 Agent 原生方式构建:AI 负责生成视觉素材,代码则赋予其生命与意义。

When to use

何时使用

  • An animated illustration, a poetic / ambient "motion poem", a visual metaphor.
  • A short brand or art piece where a beautiful illustrated scene moves with intent.
  • Any "AI-made visuals + code motion" hybrid.
  • Not for: data viz → use
    chart-animation
    ; pure headline text → use
    kinetic-typography
    ; 3D / GLSL / heavy particle systems → use
    webgl-animation
    .
  • 动画插画、诗意或氛围化的“动态诗”、视觉隐喻。
  • 简短的品牌作品或艺术片段,其中美丽的插画场景 有意图地 运动。
  • 任何“AI 生成视觉 + 代码动态”的混合创作。
  • 不适用于:数据可视化 → 使用
    chart-animation
    ;纯标题文字 → 使用
    kinetic-typography
    ;3D / GLSL / 重型粒子系统 → 使用
    webgl-animation
    。

Setup / prerequisites

设置 / 前置条件

  • Rendering needs no API key — Node +
    playwright-core
    (auto-fetches Chromium) +
    ffmpeg
    , all local and free. This covers the compose + animate + export core.
  • AI generation (assets + music) needs one API key. The simplest path is a single OpenRouter key — set
    OPENROUTER_API_KEY
    — because one key covers all three generators this skill uses:
    • vectors →
      recraft/recraft-v4.1-vector
    • painterly textures →
      google/gemini-2.5-flash-image
    • music →
      google/lyria-3-clip-preview
      (audio needs
      stream: true
      )
  • Optional alternatives:
    REPLICATE_API_KEY
    for cheaper Recraft (
    recraft-ai/recraft-v4.1-svg
    , ~$0.04 vs $0.08/image); a Google AI Studio
    GEMINI_KEY
    for Lyria direct.
  • Or bring your own assets/music (hand-drawn, any AI tool) and skip generation entirely — the motion + craft core requires no key at all.
  • 渲染无需 API key——Node +
    playwright-core
    (自动获取 Chromium)+
    ffmpeg
    ,全部在本地运行且免费。这套工具可完成合成、动画和导出的核心流程。
  • AI 生成(素材 + 音乐)需要一个 API key。 最简单的方式是使用单个 OpenRouter key——设置
    OPENROUTER_API_KEY
    ——因为一个 key 即可覆盖此 skill 使用的全部三种生成器:
    • 矢量图 →
      recraft/recraft-v4.1-vector
    • 绘画感纹理 →
      google/gemini-2.5-flash-image
    • 音乐 →
      google/lyria-3-clip-preview
      (音频需要
      stream: true
      )
  • 可选替代方案: 使用
    REPLICATE_API_KEY
    调用价格更低的 Recraft(
    recraft-ai/recraft-v4.1-svg
    ,约 $0.04/张,而另一种方案约 $0.08/张);使用 Google AI Studio 的
    GEMINI_KEY
    直接调用 Lyria。
  • 或者使用自有素材/音乐(手绘素材或任意 AI 工具生成的素材),完全跳过生成环节——动态效果与创作工艺核心无需任何 key。

The one rule that prevents 90% of failures

避免 90% 失败的一条规则

Never try to animate one big AI-generated illustration. Generate many small independent elements and let code animate each as a whole unit.
AI image/vector models output a flat pile of ungrouped paths — no
<g>
, no ids, no "this is the arm / these are the petals." You cannot rig a part inside it. Two failure modes follow:
  • Treat the whole image as static and crossfade → looks like a PowerPoint.
  • Auto-cluster the paths by proximity and wiggle each → uncanny (motion with no intent, everything wobbles).
The structure lives between assets, not inside one image. Each element is its own clean file; code moves it whole. (This is how working motion-illustrators do it — design the pieces separately, then code organizes and presents them.)
绝不要尝试让一整张大型 AI 生成插画动起来。应生成许多彼此独立的小元素,并让代码将每个元素作为整体单元进行动画处理。
AI 图像/矢量模型输出的是 扁平且未分组的路径集合——没有
<g>
、没有 id,也无法表达“这是手臂”“这些是花瓣”。你无法为其中的某个部件绑定骨骼。这会带来两种失败模式:
  • 将整张图作为静态图像并交叉淡化 → 看起来像 PowerPoint。
  • 按邻近关系自动聚类路径并让每一组抖动 → 诡异不安(运动没有意图,所有元素都在晃动)。
结构存在于素材之间,而不是一张图像内部。 每个元素都是独立且干净的文件;代码将其作为整体移动。(这正是成熟动态插画师的工作方式——分别设计各个部分,再由代码组织并呈现。)

Pipeline

流程

  1. Concept — one metaphor, ruthless restraint.
  2. Generate each element separately with AI, isolated on a plain background.
  3. Strip the background → transparent sprite.
  4. Code the motion — a deterministic seek-harness on a
    <canvas>
    ; place + animate sprites + text + grain.
  5. Render — frame-grab every frame → ffmpeg → MP4.
  6. Music — generate a custom track (Lyria), mix it in.
  1. 概念——一个隐喻,严格克制。
  2. 使用 AI 分别生成每个元素,并将其置于纯色背景上。
  3. 去除背景 → 透明精灵。
  4. 编写动态代码——在
    <canvas>
    上构建确定性 seek harness;放置并制作精灵、文本和颗粒效果的动画。
  5. 渲染——逐帧抓取 → ffmpeg → MP4。
  6. 音乐——生成定制音轨(Lyria),并混入其中。

1 · Generating assets

1 · 生成素材

  • Crisp vector elements (a flower, an icon, a creature) → Recraft v4.1 SVG.
  • Painterly textures (a watercolor wash, paper grain) → an image model (Gemini "nano-banana").
  • Specificity wins. Name a real, characterful subject — generic prompts give generic art:
PromptResult
a single delicate wildflower, soft petals…
flat, generic, cartoonish
a single **elegant poppy** on a **tall slender curved stem**, soft coral-red petals with a **delicate dark center**, one leaf, refined minimal flat vector, single isolated element, plain solid white background
a graceful, recognizable poppy — instantly "designed"
  • Always add
    no text
    — AI mangles lettering. Add every word in code (where it is exact and editable).
  • Ask for "single isolated element, plain solid white background" so it is trivial to cut out.
  • Strip the background path. Recraft draws a full-canvas white rectangle as path #0. Detect the path whose bounding box covers ~the whole viewBox and delete it → transparent sprite:
python
undefined
  • 清晰的矢量元素(花朵、图标、生物)→ Recraft v4.1 SVG。
  • 绘画感纹理(水彩晕染、纸张颗粒)→ 使用 图像模型(Gemini “nano-banana”)。
  • 具体性至关重要。 指定一个真实、鲜明且有辨识度的主体——泛泛的提示词只会产出泛泛的艺术:
提示词结果
一朵精致而柔弱的野花,柔软的花瓣……
扁平、泛化、卡通化
一朵**优雅的罂粟花**,生长在**高挑纤细且弯曲的花茎上**,柔软的珊瑚红花瓣带**精致深色花心**,一片叶子,考究的极简扁平矢量风格,单个独立元素,纯白纯色背景
优雅且易于识别的罂粟花——一眼就能看出“经过设计”
  • 始终加入
    no text
    ——AI 很容易把文字生成得乱七八糟。所有文字都应在代码中添加(这样文字准确且可编辑)。
  • 要求使用 “单个独立元素,纯白纯色背景”,这样就能轻松抠出。
  • 移除背景路径。 Recraft 会将覆盖整个画布的白色矩形绘制为 path #0。检测边界框覆盖约整个 viewBox 的路径并将其删除 → 透明精灵:
python
undefined

keep every path EXCEPT the one whose bbox spans the whole canvas

keep every path EXCEPT the one whose bbox spans the whole canvas

def is_bg(path, VBW): nums = [float(n) for n in re.findall(r'-?\d+.?\d*', d_of(path))] xs, ys = nums[0::2], nums[1::2] return xs and (max(xs)-min(xs)) > VBW0.92 and (max(ys)-min(ys)) > VBW0.92

- Recraft v4.1 SVG format: `<path …></path>` (not self-closing), `viewBox="0 0 2048 2048"`, `transform="translate(x,y)"`, absolute coordinates.
def is_bg(path, VBW): nums = [float(n) for n in re.findall(r'-?\d+.?\d*', d_of(path))] xs, ys = nums[0::2], nums[1::2] return xs and (max(xs)-min(xs)) > VBW0.92 and (max(ys)-min(ys)) > VBW0.92

- Recraft v4.1 SVG 格式:`<path …></path>`(不是自闭合标签)、`viewBox="0 0 2048 2048"`、`transform="translate(x,y)"`、绝对坐标。

2 · The deterministic seek harness (the key to clean rendering)

2 · 确定性 seek harness(干净渲染的关键)

Every visible value is a pure function of time
t
— never a
requestAnimationFrame
loop or a CSS transition (those desync from the frame-grabber and flicker).
js
window.__T = totalSeconds;                 // total duration
window.__seek = (t) => render(t);          // bar width, x/y, opacity, scale — all derived from t
// on load: render the frame named in the URL
window.__seek(parseFloat(new URLSearchParams(location.search).get('t')) || 0);
A one-browser Playwright loop seeks
t = 0, 1/30, 2/30 …
, screenshots each, then ffmpeg assembles them (use even dimensions +
yuv420p
). For stateful sims (particles), step the sim forward deterministically with a seeded RNG so every render is identical.
每一个可见值都必须是 时间
t
的纯函数
——绝不要使用
requestAnimationFrame
循环或 CSS transition(它们会与抓帧器失去同步并产生闪烁)。
js
window.__T = totalSeconds;                 // total duration
window.__seek = (t) => render(t);          // bar width, x/y, opacity, scale — all derived from t
// on load: render the frame named in the URL
window.__seek(parseFloat(new URLSearchParams(location.search).get('t')) || 0);
使用单个浏览器的 Playwright 循环,依次 seek 到
t = 0, 1/30, 2/30 …
,为每一帧截图,然后由 ffmpeg 将其组装起来(使用 偶数 尺寸 +
yuv420p
)。对于有状态模拟(粒子),使用 带种子的 RNG 确定性地逐步推进模拟,确保每次渲染完全一致。

3 · Animating sprites

3 · 制作精灵动画

  • Load each asset as an
    Image
    (inline base64 data-URI so the HTML is self-contained);
    drawImage
    per instance inside
    save/translate/rotate/scale/restore
    .
  • Anchor each sprite at its motion pivot (base / center / a corner — whatever the motion needs). E.g. to rise from a line:
    translate(x, baseY)
    then draw at
    (-w/2, -h)
    .
  • Match the entrance to the idea, don't reflex to "grow": a count-up, a split/double, a slide-in, a flood, a snap, a scale-from-0 — each says something different. Idle life: gentle
    sin(t)
    drift.
  • Add a grain overlay (seeded noise) for a hand-made, Softcore texture.
  • In capture, gate on an
    window.__ready()
    flag once all images have decoded.
  • 将每个素材加载为
    Image
    (使用内联 base64 data-URI,使 HTML 自包含);为每个实例在
    save/translate/rotate/scale/restore
    中调用
    drawImage
    。
  • 将每个精灵 锚定在其动态支点(底边/中心/角落——根据动态需求决定)。例如,要让元素从一条线上升起:先
    translate(x, baseY)
    ,再在
    (-w/2, -h)
    处绘制。
  • 让入场方式与概念相匹配,不要本能地选择“生长”:计数增长、分裂/成双、滑入、涌入、瞬间弹入、从 0 缩放出现——每一种都表达不同含义。闲置时也要有生命感:轻柔的
    sin(t)
    漂移。
  • 添加 颗粒叠加层(带种子的噪声),营造手工质朴的 Softcore 质感。
  • 抓取时,在所有图片解码完成后,通过
    window.__ready()
    标志位进行门控。

4 · Craft — what makes it good, not just moving

4 · 创作工艺——让它不仅会动,还要真正好看

  • Let the concept choose the visual — never default to one device. The motion vocabulary must be derived from this idea, not reused: compounding → a dot doubling until it floods the screen (not a plant); a blank page → the first word breaking a dam of text (not a sprout); overload → tabs/windows multiplying into noise. Reusing one device — "a thing grows up from the ground" — across unrelated concepts is the #1 reason these go stale and generic. If you reach for "something grows" a second time, stop and ask what the concept actually looks like. (The growing-plant in the original garden piece worked only because the concept was literally botanical.)
  • Causality. Tie cause → effect literally (an input lands → something happens at that spot). Loosely-related parallel events read as random noise.
  • Restraint. Motion needs fewer elements than static design — too many and it gets noisy in motion. Keep only the core; don't overdo it.
  • Spotlight the hero. When one element matters (the one that "made it"), dim the rest and lift it — a halo, a scale, a color shift.
  • Rhythm: resolve → a beat of stillness → reflect. A closing line is a looking-back statement; it only lands after the action has stopped. Let the motion finish, hold a beat, then reveal the slogan — never overlap the conclusion with things still moving.
  • Easing. Never linear on anything a viewer reads. Ease the value, not just opacity. Overshoot for small pops; slow ease-out for growth.
  • Semantics — don't self-sabotage. If the piece depicts failure/withering, do not label it with your own product's features (it reads as "our product fails at its core jobs"). Use neutral or process language instead.
  • 让概念决定视觉表达——绝不要默认套用某一种手法。 动态语汇必须源于 这个创意,不能反复挪用:复利累积 → 一个点不断倍增,直至铺满屏幕(而不是植物);空白页面 → 第一个词冲破文字大坝(而不是嫩芽);过载 → 标签页/窗口不断增殖,最终化为噪声。对于不相关的概念反复使用同一种手法——“一个东西从地面长起来”——正是这些作品显得陈旧且泛泛的首要原因。如果你第二次想到“某种东西生长”,就停下来问问这个概念实际上应该是什么样。(原始花园作品中的生长植物之所以成立,仅仅因为该概念在字面上就是植物主题。)
  • 因果关系。 将原因 → 结果直接关联起来(一个输入落下 → 该位置发生某种变化)。松散相关却彼此平行的运动会看起来像随机噪声。
  • 克制。 动态设计所需的元素应少于静态设计——元素太多,动起来就会变得嘈杂。只保留核心内容;不要过度设计。
  • 突出主角。 当某个元素至关重要(那个“促成结果”的元素)时,压暗其余元素并突出它——光晕、缩放或色彩变化。
  • 节奏:收束 → 静止一拍 → 回望。 结尾文案是一句“回望式”的陈述;只有动作停止后才能真正成立。让动态效果完成,停留一拍,然后再揭示标语——绝不要在仍有元素运动时让结论与其重叠。
  • 缓动。 对观众会阅读的任何内容,绝不要使用线性缓动。应对 数值 进行缓动,而不只是透明度。小幅弹出可使用 overshoot;生长使用慢速 ease-out。
  • 语义——不要自我拆台。 如果作品表现的是失败/凋零,绝不要用它来标注你自己产品的功能(这会让人理解为“我们的产品连核心职责都无法完成”)。改用中性或过程性语言。

5 · Music

5 · 音乐

Generate a custom track with Lyria 3 (OpenRouter
google/lyria-3-clip-preview
). It is AI-generated, so it is royalty-free. Audio output requires
stream: true
— chunks arrive as base64 in
delta.audio.data
; concatenate and decode to MP3. Mix with ffmpeg: trim to length, fade in/out, duck the volume (~0.5) under any narration.
使用 Lyria 3 生成定制音轨(OpenRouter
google/lyria-3-clip-preview
)。它由 AI 生成,因此可免版税使用。音频输出需要
stream: true
——数据块以 base64 形式出现在
delta.audio.data
中;将其拼接并解码为 MP3。用 ffmpeg 混音:裁剪到目标长度、淡入淡出,并在旁白下方将音量压低(约 0.5)。

6 · Verify loop (do not skip)

6 · 验证循环(不要跳过)

Render the piece, build a full-duration contact sheet (sample frames across the whole timeline, not just the first seconds), and read it yourself: blank frames? overlapping rows? does the concept actually read? Fix and re-render. This deliver-and-verify loop is what separates "it ran" from "it's good."
渲染作品,构建覆盖 完整时长 的接触表(contact sheet)(采样 整条时间线 上的帧,而不只是开头几秒),并 亲自查看检查:是否存在空白帧?各行是否重叠?概念是否真的清晰可辨?修复后重新渲染。这种“交付—验证”循环,正是区分“它能运行”和“它做得好”的关键。

references/

references/

  • asset-pipeline.md
    — asset prompting, background-strip code, Recraft/Gemini format notes
  • render-harness.md
    — full seek-harness HTML + Playwright capture + ffmpeg recipe
  • craft.md
    — causality, rhythm, restraint, spotlight, with worked examples

The craft behind iart.ai. Cost reference: a Recraft SVG ≈ $0.04, a Lyria track ≈ cents — a whole finished piece comes in under $1.
  • asset-pipeline.md
    ——素材提示词、背景移除代码、Recraft/Gemini 格式说明
  • render-harness.md
    ——完整的 seek-harness HTML + Playwright 抓帧 + ffmpeg 方案
  • craft.md
    ——因果关系、节奏、克制、聚光,以及实战示例

iart.ai 背后的创作工艺。成本参考:一张 Recraft SVG ≈ $0.04,一首 Lyria 音轨 ≈ 数美分——一件完整成品的总成本低于 $1。