huashu-design-html-native

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Huashu Design — HTML-Native Design Skill

Huashu Design — 原生HTML设计技能

Skill by ara.so — Daily 2026 Skills collection.
Huashu Design turns natural-language requests into deliverable designs — interactive prototypes, animated slides, motion exports, and infographics — entirely in HTML/CSS/JS, no Figma or GUI required. Install it once into your agent; from then on say what you want and receive a finished file.

ara.so开发的技能——属于Daily 2026 Skills系列。
Huashu Design可将自然语言需求转化为可交付的设计成果——交互式原型、动画幻灯片、动态导出内容及信息图——完全基于HTML/CSS/JS实现,无需Figma或GUI工具。只需将其安装到你的Agent中,之后只需说出需求即可获得成品文件。

Installation

安装

bash
npx skills add alchaincyf/huashu-design
Compatible with Claude Code, Cursor, Codex, OpenClaw, Hermes, and any agent that reads
SKILL.md
.

bash
npx skills add alchaincyf/huashu-design
兼容Claude Code、Cursor、Codex、OpenClaw、Hermes及所有支持读取
SKILL.md
的Agent。

What It Produces

输出成果

OutputFormatTypical Time
Interactive prototype (App/Web)Single-file HTML, iPhone/Android bezel, clickable10–15 min
Presentation deckHTML (browser) + editable PPTX (real text boxes)15–25 min
Timeline animationMP4 (25/60 fps) + GIF (palette-optimized) + BGM8–12 min
Design variants3+ side-by-side, Tweaks panel, localStorage10 min
Infographic / data vizPrint-quality, CSS Grid, exportable PDF/PNG/SVG10 min
Design direction advice5 schools × 20 philosophies, 3 directions + demos5 min
5-dimension expert critiqueRadar chart + Keep/Fix/Quick Wins list3 min

输出类型格式典型耗时
交互式原型(应用/网页)单文件HTML,带iPhone/Android边框,支持点击10–15分钟
演示文稿HTML(浏览器端)+ 可编辑PPTX(真实文本框)15–25分钟
时间轴动画MP4(25/60帧)+ GIF(调色板优化)+ 背景音乐8–12分钟
设计变体3+并列展示,带调整面板,支持localStorage10分钟
信息图/数据可视化印刷级质量,CSS Grid布局,可导出PDF/PNG/SVG10分钟
设计方向建议5大流派×20种理念,3种方向+演示样例5分钟
5维度专家评审雷达图+保留/修复/快速改进清单3分钟

Repository Structure

仓库结构

huashu-design/
├── SKILL.md                  # Agent-facing spec (the real instructions)
├── assets/
│   ├── animations.jsx        # Stage + Sprite + Easing + interpolate APIs
│   ├── ios_frame.jsx         # iPhone 15 Pro bezel (Dynamic Island, Home bar)
│   ├── android_frame.jsx
│   ├── macos_window.jsx
│   ├── browser_window.jsx
│   ├── deck_stage.js         # HTML slide engine
│   ├── deck_index.html       # Multi-file deck assembler
│   ├── design_canvas.jsx     # Side-by-side variant display
│   ├── showcases/            # 24 prebuilt examples (8 scenes × 3 styles)
│   └── bgm-*.mp3             # 6 scene-matched background tracks
├── references/
│   ├── animation-pitfalls.md
│   ├── design-styles.md      # 20 design philosophies detail
│   ├── slide-decks.md
│   ├── editable-pptx.md
│   ├── critique-guide.md
│   └── video-export.md
├── scripts/
│   ├── render-video.js       # HTML → MP4 via Playwright
│   ├── convert-formats.sh    # MP4 → 60fps interpolation + GIF
│   ├── add-music.sh          # Mux BGM into MP4
│   ├── export_deck_pdf.mjs
│   ├── export_deck_pptx.mjs
│   └── html2pptx.js          # DOM computedStyle → real PPTX objects
└── demos/                    # 9 capability demos (c*/w* series)

huashu-design/
├── SKILL.md                  # Agent面向的规范文档(核心说明)
├── assets/
│   ├── animations.jsx        # 舞台+精灵+缓动+插值API
│   ├── ios_frame.jsx         # iPhone 15 Pro边框(灵动岛、Home栏)
│   ├── android_frame.jsx
│   ├── macos_window.jsx
│   ├── browser_window.jsx
│   ├── deck_stage.js         # HTML幻灯片引擎
│   ├── deck_index.html       # 多文件幻灯片组装器
│   ├── design_canvas.jsx     # 并列变体展示画布
│   ├── showcases/            # 24个预构建示例(8种场景×3种风格)
│   └── bgm-*.mp3             # 6个场景匹配的背景音乐轨道
├── references/
│   ├── animation-pitfalls.md
│   ├── design-styles.md      # 20种设计理念详情
│   ├── slide-decks.md
│   ├── editable-pptx.md
│   ├── critique-guide.md
│   └── video-export.md
├── scripts/
│   ├── render-video.js       # 通过Playwright将HTML转为MP4
│   ├── convert-formats.sh    # MP4转60帧插值+GIF
│   ├── add-music.sh          # 将背景音乐混入MP4
│   ├── export_deck_pdf.mjs
│   ├── export_deck_pptx.mjs
│   └── html2pptx.js          # DOM计算样式转真实PPTX对象
└── demos/                    # 9个能力演示(c*/w*系列)

Core Concepts

核心概念

1. Junior Designer Workflow (Default Mode)

1. 初级设计师工作流(默认模式)

The agent never starts blind. Before any task it:
  1. Shows a one-shot question list — waits for batch answers before touching code
  2. Writes
    assumptions
    ,
    placeholders
    , and
    reasoning
    comments inside the HTML
  3. Shows an early skeleton (even gray boxes) — gets approval
  4. Fills content → generates variations → adds Tweaks panel — shows each step
  5. Runs Playwright visual check before final delivery
Agent绝不会盲目开始任务。在执行任何任务前,它会:
  1. 展示一次性问题清单——等待批量回复后再编写代码
  2. 在HTML中写入
    assumptions
    (假设)、
    placeholders
    (占位符)和
    reasoning
    (推理)注释
  3. 展示早期框架(甚至是灰色盒子)——获得批准
  4. 填充内容→生成变体→添加调整面板——展示每一步
  5. 在最终交付前运行Playwright视觉检查

2. Brand Asset Protocol (Mandatory for Named Brands)

2. 品牌资产协议(指定品牌必填)

When the task involves a specific brand (Stripe, Linear, Anthropic, your company):
StepAction
1 · AskDoes the user have brand guidelines?
2 · Search
<brand>.com/brand
,
brand.<brand>.com
,
<brand>.com/press
3 · DownloadSVG file → full page HTML → product screenshot color-pick (three fallbacks)
4 · Extract
grep
all
#xxxxxx
from assets, rank by frequency, filter black/white/gray
5 · Lock specWrite
brand-spec.md
+ CSS custom properties; all HTML uses
var(--brand-*)
Never guess brand colors from memory. Always extract from downloaded assets.
css
/* brand-spec.md output example */
:root {
  --brand-primary:   #635BFF;   /* Stripe violet — freq: 847 */
  --brand-secondary: #0A2540;   /* Stripe navy   — freq: 312 */
  --brand-accent:    #00D924;   /* Stripe green  — freq: 89  */
}
当任务涉及特定品牌(Stripe、Linear、Anthropic或你的公司)时:
步骤操作
1 · 询问用户是否有品牌指南?
2 · 搜索
<brand>.com/brand
brand.<brand>.com
<brand>.com/press
3 · 下载SVG文件→完整页面HTML→产品截图取色(三种备用方案)
4 · 提取从资产中
grep
所有
#xxxxxx
颜色值,按频率排序,过滤黑/白/灰色
5 · 锁定规范编写
brand-spec.md
+CSS自定义属性;所有HTML使用
var(--brand-*)
绝不要凭记忆猜测品牌颜色。务必从下载的资产中提取。
css
/* brand-spec.md输出示例 */
:root {
  --brand-primary:   #635BFF;   /* Stripe紫色 — 出现频率: 847 */
  --brand-secondary: #0A2540;   /* Stripe深蓝色 — 出现频率: 312 */
  --brand-accent:    #00D924;   /* Stripe绿色 — 出现频率: 89  */
}

3. Design Direction Advisor (Fallback)

3. 设计方向顾问(备选模式)

Triggered when the request is too vague to start. The agent:
  • Picks 3 directions from different schools out of 5 schools × 20 philosophies
  • Returns each with: representative works, mood keywords, reference designers
  • Generates 3 parallel visual demos for the user to choose
  • Then enters the Junior Designer main flow
The 5 schools and 20 philosophies live in
references/design-styles.md
. Examples:
SchoolPhilosophies (subset)
Modernist FunctionalismSwiss Grid, Bauhaus Utility, Dieter Rams Reduction
Emotional ExpressionismMemphis Color, Brutalist Raw, Maximalist Baroque
Digital NativeGlassmorphism, Neumorphism, Cyberpunk Neon
Cultural FusionWabi-Sabi, Bauhaus East, Art Nouveau Revival
Systems ThinkingMaterial Design, IBM Carbon, Apple HIG
当请求过于模糊无法启动时触发。Agent会:
  • 从5大流派×20种理念中挑选3种不同流派的方向
  • 返回每个方向的代表作品、氛围关键词、参考设计师
  • 生成3个平行视觉演示供用户选择
  • 随后进入初级设计师主工作流
5大流派和20种理念存于
references/design-styles.md
中。示例:
流派理念(子集)
现代功能主义瑞士网格、包豪斯实用主义、迪特·拉姆斯简约
情感表现主义孟菲斯色彩、粗野主义原始风格、极繁主义巴洛克
数字原生玻璃态设计、新拟态、赛博朋克霓虹
文化融合侘寂、东方包豪斯、新艺术复兴
系统思维Material Design、IBM Carbon、Apple HIG

4. Motion Design Engine

4. 动效设计引擎

The animation system uses four composable primitives from
assets/animations.jsx
:
js
// Stage: defines total duration and canvas
const stage = useStage({ duration: 5000, width: 1920, height: 1080 });

// Sprite: a timed element (appears at t=500ms, lasts 2000ms)
const logo = useSprite({ start: 500, duration: 2000 });

// interpolate: map time → value with easing
const x = interpolate(stage.t, [0, 1000], [200, 0], Easing.easeOutExpo);
const opacity = interpolate(stage.t, [0, 500], [0, 1], Easing.linear);

// Render
return (
  <div style={{
    transform: `translateX(${x}px)`,
    opacity,
    ...logo.style,   // visibility gating included
  }}>
    {children}
  </div>
);
动画系统使用
assets/animations.jsx
中的四个可组合原语:
js
// Stage: 定义总时长和画布
const stage = useStage({ duration: 5000, width: 1920, height: 1080 });

// Sprite: 带时间属性的元素(在t=500ms出现,持续2000ms)
const logo = useSprite({ start: 500, duration: 2000 });

// interpolate: 通过缓动函数将时间映射为数值
const x = interpolate(stage.t, [0, 1000], [200, 0], Easing.easeOutExpo);
const opacity = interpolate(stage.t, [0, 500], [0, 1], Easing.linear);

// 渲染
return (
  <div style={{
    transform: `translateX(${x}px)`,
    opacity,
    ...logo.style,   // 包含可见性控制
  }}>
    {children}
  </div>
);

5. Anti-AI-Slop Rules

5. 反AI劣质设计规则

Avoid the visual least-common-denominator:
  • ❌ Purple gradients, emoji icons, left border-accent cards, SVG-drawn human faces, Inter as display font
  • text-wrap: pretty
    , CSS Grid layouts, curated serif display fonts,
    oklch()
    color space, actual whitespace

避免视觉上的最低公分母:
  • ❌ 紫色渐变、表情图标、左侧边框强调卡片、SVG绘制人脸、Inter作为标题字体
  • text-wrap: pretty
    、CSS Grid布局、精选衬线标题字体、
    oklch()
    色彩空间、真实留白

Starter Patterns

入门模板

iOS App Prototype

iOS应用原型

html
<!-- Uses assets/ios_frame.jsx internally -->
<!-- Agent generates a self-contained HTML file like this: -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>AI Pomodoro — Prototype</title>
  <style>
    :root {
      --ios-width: 393px;
      --ios-height: 852px;
      --brand-primary: #FF3B30;
    }

    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      background: #1a1a1a;
      font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif;
    }

    .device {
      width: var(--ios-width);
      height: var(--ios-height);
      background: #000;
      border-radius: 54px;
      box-shadow:
        0 0 0 2px #3a3a3a,
        0 0 0 6px #1a1a1a,
        0 40px 80px rgba(0,0,0,0.8);
      overflow: hidden;
      position: relative;
    }

    /* Dynamic Island */
    .dynamic-island {
      position: absolute;
      top: 12px;
      left: 50%;
      transform: translateX(-50%);
      width: 126px;
      height: 37px;
      background: #000;
      border-radius: 20px;
      z-index: 100;
    }

    /* Screen states */
    .screen { display: none; width: 100%; height: 100%; }
    .screen.active { display: flex; flex-direction: column; }

    /* Navigation */
    [data-go] { cursor: pointer; }
  </style>
</head>
<body>
  <div class="device">
    <div class="dynamic-island"></div>

    <!-- Screen: Home -->
    <div class="screen active" id="screen-home">
      <div style="flex:1; display:flex; flex-direction:column; align-items:center;
                  justify-content:center; padding: 60px 32px 0; background:#fff;">
        <div style="font-size:72px; font-weight:700; color:var(--brand-primary);
                    font-variant-numeric:tabular-nums;">25:00</div>
        <div style="margin-top:8px; color:#6e6e73; font-size:17px;">Focus Session</div>
        <button data-go="screen-running"
          style="margin-top:48px; background:var(--brand-primary); color:#fff;
                 border:none; border-radius:50%; width:80px; height:80px;
                 font-size:32px; cursor:pointer;"></button>
      </div>
    </div>

    <!-- Screen: Running -->
    <div class="screen" id="screen-running">
      <div style="flex:1; display:flex; flex-direction:column; align-items:center;
                  justify-content:center; padding:60px 32px 0; background:#fff;">
        <div style="font-size:72px; font-weight:700; color:var(--brand-primary);">24:59</div>
        <button data-go="screen-home"
          style="margin-top:48px; background:#f2f2f7; color:#000;
                 border:none; border-radius:20px; padding:16px 40px;
                 font-size:17px; cursor:pointer;">Stop</button>
      </div>
    </div>
  </div>

  <script>
    // State-driven navigation
    document.querySelectorAll('[data-go]').forEach(el => {
      el.addEventListener('click', () => {
        document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
        document.getElementById(el.dataset.go)?.classList.add('active');
      });
    });
  </script>
</body>
</html>
html
<!-- 内部使用assets/ios_frame.jsx -->
<!-- Agent会生成这样的独立HTML文件: -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>AI Pomodoro — Prototype</title>
  <style>
    :root {
      --ios-width: 393px;
      --ios-height: 852px;
      --brand-primary: #FF3B30;
    }

    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      background: #1a1a1a;
      font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif;
    }

    .device {
      width: var(--ios-width);
      height: var(--ios-height);
      background: #000;
      border-radius: 54px;
      box-shadow:
        0 0 0 2px #3a3a3a,
        0 0 0 6px #1a1a1a,
        0 40px 80px rgba(0,0,0,0.8);
      overflow: hidden;
      position: relative;
    }

    /* 灵动岛 */
    .dynamic-island {
      position: absolute;
      top: 12px;
      left: 50%;
      transform: translateX(-50%);
      width: 126px;
      height: 37px;
      background: #000;
      border-radius: 20px;
      z-index: 100;
    }

    /* 屏幕状态 */
    .screen { display: none; width: 100%; height: 100%; }
    .screen.active { display: flex; flex-direction: column; }

    /* 导航 */
    [data-go] { cursor: pointer; }
  </style>
</head>
<body>
  <div class="device">
    <div class="dynamic-island"></div>

    <!-- 屏幕:首页 -->
    <div class="screen active" id="screen-home">
      <div style="flex:1; display:flex; flex-direction:column; align-items:center;
                  justify-content:center; padding: 60px 32px 0; background:#fff;">
        <div style="font-size:72px; font-weight:700; color:var(--brand-primary);
                    font-variant-numeric:tabular-nums;">25:00</div>
        <div style="margin-top:8px; color:#6e6e73; font-size:17px;">Focus Session</div>
        <button data-go="screen-running"
          style="margin-top:48px; background:var(--brand-primary); color:#fff;
                 border:none; border-radius:50%; width:80px; height:80px;
                 font-size:32px; cursor:pointer;"></button>
      </div>
    </div>

    <!-- 屏幕:运行中 -->
    <div class="screen" id="screen-running">
      <div style="flex:1; display:flex; flex-direction:column; align-items:center;
                  justify-content:center; padding:60px 32px 0; background:#fff;">
        <div style="font-size:72px; font-weight:700; color:var(--brand-primary);">24:59</div>
        <button data-go="screen-home"
          style="margin-top:48px; background:#f2f2f7; color:#000;
                 border:none; border-radius:20px; padding:16px 40px;
                 font-size:17px; cursor:pointer;">Stop</button>
      </div>
    </div>
  </div>

  <script>
    // 状态驱动导航
    document.querySelectorAll('[data-go]').forEach(el => {
      el.addEventListener('click', () => {
        document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
        document.getElementById(el.dataset.go)?.classList.add('active');
      });
    });
  </script>
</body>
</html>

HTML Slide Deck

HTML幻灯片

html
<!-- Single-file deck with keyboard navigation -->
<!DOCTYPE html>
<html>
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: #0a0a0a; font-family: "Inter", sans-serif; }

    .deck { width: 100vw; height: 100vh; }
    .slide {
      display: none;
      width: 100%;
      height: 100%;
      padding: 80px;
      flex-direction: column;
      justify-content: center;
    }
    .slide.active { display: flex; }

    /* Progress bar */
    .progress {
      position: fixed;
      bottom: 0; left: 0;
      height: 3px;
      background: var(--accent, #635BFF);
      transition: width 0.3s ease;
    }
  </style>
</head>
<body>
  <div class="deck">
    <div class="slide active" style="background:#0a0a0a; color:#fff;">
      <h1 style="font-size:clamp(2rem,6vw,5rem); font-weight:800; line-height:1.1;
                 text-wrap:pretty;">The Future of AI Design</h1>
      <p style="margin-top:24px; font-size:1.25rem; color:#888;">May 2026</p>
    </div>

    <div class="slide" style="background:#fff; color:#0a0a0a;">
      <h2 style="font-size:3rem; font-weight:700;">Key Insight</h2>
      <p style="margin-top:32px; font-size:1.5rem; line-height:1.6;
                max-width:60ch; text-wrap:pretty;">
        Design tools are disappearing. The interface is the conversation.
      </p>
    </div>
  </div>

  <div class="progress" id="progress"></div>

  <script>
    const slides = document.querySelectorAll('.slide');
    let current = 0;

    function go(n) {
      slides[current].classList.remove('active');
      current = Math.max(0, Math.min(n, slides.length - 1));
      slides[current].classList.add('active');
      document.getElementById('progress').style.width =
        `${((current + 1) / slides.length) * 100}%`;
    }

    document.addEventListener('keydown', e => {
      if (e.key === 'ArrowRight' || e.key === ' ') go(current + 1);
      if (e.key === 'ArrowLeft') go(current - 1);
    });

    go(0);
  </script>
</body>
</html>
html
<!-- 带键盘导航的单文件幻灯片 -->
<!DOCTYPE html>
<html>
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: #0a0a0a; font-family: "Inter", sans-serif; }

    .deck { width: 100vw; height: 100vh; }
    .slide {
      display: none;
      width: 100%;
      height: 100%;
      padding: 80px;
      flex-direction: column;
      justify-content: center;
    }
    .slide.active { display: flex; }

    /* 进度条 */
    .progress {
      position: fixed;
      bottom: 0; left: 0;
      height: 3px;
      background: var(--accent, #635BFF);
      transition: width 0.3s ease;
    }
  </style>
</head>
<body>
  <div class="deck">
    <div class="slide active" style="background:#0a0a0a; color:#fff;">
      <h1 style="font-size:clamp(2rem,6vw,5rem); font-weight:800; line-height:1.1;
                 text-wrap:pretty;">The Future of AI Design</h1>
      <p style="margin-top:24px; font-size:1.25rem; color:#888;">May 2026</p>
    </div>

    <div class="slide" style="background:#fff; color:#0a0a0a;">
      <h2 style="font-size:3rem; font-weight:700;">Key Insight</h2>
      <p style="margin-top:32px; font-size:1.5rem; line-height:1.6;
                max-width:60ch; text-wrap:pretty;">
        Design tools are disappearing. The interface is the conversation.
      </p>
    </div>
  </div>

  <div class="progress" id="progress"></div>

  <script>
    const slides = document.querySelectorAll('.slide');
    let current = 0;

    function go(n) {
      slides[current].classList.remove('active');
      current = Math.max(0, Math.min(n, slides.length - 1));
      slides[current].classList.add('active');
      document.getElementById('progress').style.width =
        `${((current + 1) / slides.length) * 100}%`;
    }

    document.addEventListener('keydown', e => {
      if (e.key === 'ArrowRight' || e.key === ' ') go(current + 1);
      if (e.key === 'ArrowLeft') go(current - 1);
    });

    go(0);
  </script>
</body>
</html>

Tweaks Panel (Design Variants)

调整面板(设计变体)

html
<script>
  // Parameterized design system with localStorage persistence
  const TWEAKS = {
    colorScheme: { options: ['midnight', 'warm', 'ocean'], default: 'midnight' },
    typeScale:   { options: ['compact', 'comfortable', 'spacious'], default: 'comfortable' },
    density:     { options: ['dense', 'balanced', 'airy'], default: 'balanced' },
  };

  const themes = {
    midnight: { '--bg': '#0a0a0a', '--fg': '#ffffff', '--accent': '#635BFF' },
    warm:     { '--bg': '#faf6f0', '--fg': '#1a1208', '--accent': '#d4793a' },
    ocean:    { '--bg': '#f0f7ff', '--fg': '#0a1628', '--accent': '#0066cc' },
  };

  function applyTweak(key, value) {
    localStorage.setItem(`tweak-${key}`, value);
    if (key === 'colorScheme') {
      Object.entries(themes[value]).forEach(([prop, val]) =>
        document.documentElement.style.setProperty(prop, val));
    }
  }

  // Restore on load
  Object.keys(TWEAKS).forEach(key => {
    const saved = localStorage.getItem(`tweak-${key}`) || TWEAKS[key].default;
    applyTweak(key, saved);
  });
</script>
html
<script>
  // 带localStorage持久化的参数化设计系统
  const TWEAKS = {
    colorScheme: { options: ['midnight', 'warm', 'ocean'], default: 'midnight' },
    typeScale:   { options: ['compact', 'comfortable', 'spacious'], default: 'comfortable' },
    density:     { options: ['dense', 'balanced', 'airy'], default: 'balanced' },
  };

  const themes = {
    midnight: { '--bg': '#0a0a0a', '--fg': '#ffffff', '--accent': '#635BFF' },
    warm:     { '--bg': '#faf6f0', '--fg': '#1a1208', '--accent': '#d4793a' },
    ocean:    { '--bg': '#f0f7ff', '--fg': '#0a1628', '--accent': '#0066cc' },
  };

  function applyTweak(key, value) {
    localStorage.setItem(`tweak-${key}`, value);
    if (key === 'colorScheme') {
      Object.entries(themes[value]).forEach(([prop, val]) =>
        document.documentElement.style.setProperty(prop, val));
    }
  }

  // 加载时恢复设置
  Object.keys(TWEAKS).forEach(key => {
    const saved = localStorage.getItem(`tweak-${key}`) || TWEAKS[key].default;
    applyTweak(key, saved);
  });
</script>

Video Export Pipeline

视频导出流程

bash
undefined
bash
undefined

1. Render HTML animation to MP4

1. 将HTML动画渲染为MP4

node scripts/render-video.js
--input ./animation.html
--output ./out/animation.mp4
--fps 25
--duration 10000
node scripts/render-video.js
--input ./animation.html
--output ./out/animation.mp4
--fps 25
--duration 10000

2. Upscale to 60fps with frame interpolation

2. 通过帧插值升级到60fps

bash scripts/convert-formats.sh
--input ./out/animation.mp4
--fps 60
--output ./out/animation-60fps.mp4
bash scripts/convert-formats.sh
--input ./out/animation.mp4
--fps 60
--output ./out/animation-60fps.mp4

3. Export palette-optimized GIF

3. 导出调色板优化的GIF

bash scripts/convert-formats.sh
--input ./out/animation.mp4
--format gif
--width 800
--output ./out/animation.gif
bash scripts/convert-formats.sh
--input ./out/animation.mp4
--format gif
--width 800
--output ./out/animation.gif

4. Add background music

4. 添加背景音乐

bash scripts/add-music.sh
--video ./out/animation.mp4
--audio ./assets/bgm-cinematic.mp3
--output ./out/animation-final.mp4

```js
// render-video.js uses Playwright internally
const { chromium } = require('playwright');

async function renderVideo({ input, output, fps = 25, duration = 10000 }) {
  const browser = await chromium.launch();
  const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } });

  await page.goto(`file://${path.resolve(input)}`);

  // Frame-by-frame capture
  const frames = [];
  const totalFrames = Math.ceil((duration / 1000) * fps);

  for (let i = 0; i < totalFrames; i++) {
    await page.evaluate(t => window.__seekTo?.(t), (i / fps) * 1000);
    frames.push(await page.screenshot({ type: 'png' }));
  }

  await browser.close();
  // Encode frames → MP4 via ffmpeg
  await encodeFrames(frames, output, fps);
}
bash scripts/add-music.sh
--video ./out/animation.mp4
--audio ./assets/bgm-cinematic.mp3
--output ./out/animation-final.mp4

```js
// render-video.js内部使用Playwright
const { chromium } = require('playwright');

async function renderVideo({ input, output, fps = 25, duration = 10000 }) {
  const browser = await chromium.launch();
  const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } });

  await page.goto(`file://${path.resolve(input)}`);

  // 逐帧捕获
  const frames = [];
  const totalFrames = Math.ceil((duration / 1000) * fps);

  for (let i = 0; i < totalFrames; i++) {
    await page.evaluate(t => window.__seekTo?.(t), (i / fps) * 1000);
    frames.push(await page.screenshot({ type: 'png' }));
  }

  await browser.close();
  // 将帧编码为MP4(通过ffmpeg)
  await encodeFrames(frames, output, fps);
}

PPTX Export (Real Text Boxes)

PPTX导出(真实文本框)

bash
undefined
bash
undefined

Export HTML deck to editable PowerPoint

将HTML幻灯片导出为可编辑的PowerPoint文件

node scripts/export_deck_pptx.mjs
--input ./deck.html
--output ./deck.pptx
node scripts/export_deck_pptx.mjs
--input ./deck.html
--output ./deck.pptx

Export to PDF (vector)

导出为PDF(矢量格式)

node scripts/export_deck_pdf.mjs
--input ./deck.html
--output ./deck.pdf

The `html2pptx.js` converter reads `getComputedStyle()` on every DOM element and maps CSS properties to real PowerPoint text boxes, shapes, and images — output is editable in PowerPoint/Keynote, not an image dump.
node scripts/export_deck_pdf.mjs
--input ./deck.html
--output ./deck.pdf

`html2pptx.js`转换器会读取每个DOM元素的`getComputedStyle()`,并将CSS属性映射为真实的PowerPoint文本框、形状和图片——输出文件可在PowerPoint/Keynote中编辑,而非图片转储。

5-Dimension Expert Critique

5维度专家评审

Ask: "Do a 5-dimension design critique of this file"
The agent scores 0–10 on:
DimensionWhat It Checks
Philosophical ConsistencyDoes the design commit to one visual language?
Visual HierarchyCan a stranger scan and know what matters in 3 seconds?
Detail ExecutionSpacing, kerning, alignment — are they precise?
FunctionalityDoes every element earn its place?
InnovationIs there a distinctive creative choice?
Output: SVG radar chart + structured
Keep / Fix / Quick Wins
list with actionable steps.

询问:“对该文件进行5维度设计评审”
Agent会在以下维度给出0–10分:
维度评审内容
理念一致性设计是否遵循统一的视觉语言?
视觉层级陌生人能否在3秒内扫描并了解核心信息?
细节执行间距、字距、对齐是否精确?
功能性每个元素是否有存在的必要?
创新性是否有独特的创意选择?
输出:SVG雷达图+结构化的
保留/修复/快速改进
清单及可操作步骤。

Prompt Examples That Work Well

有效提示示例

undefined
undefined

Prototype

原型制作

"Make a clickable iOS prototype for an AI journaling app — 4 core screens"
"制作一个可点击的AI日记应用iOS原型——包含4个核心屏幕"

Slide deck

幻灯片制作

"Create a 10-slide pitch deck for a B2B SaaS product, suggest 3 style directions"
"为一款B2B SaaS产品创建10页演示文稿,提供3种风格方向"

Animation

动画制作

"Animate this product launch sequence, 30 seconds, export MP4 with music"
"为这个产品发布序列制作动画,时长30秒,导出带音乐的MP4"

Infographic

信息图制作

"Visualize this dataset as a magazine-quality infographic, export PNG 300dpi"
"将该数据集可视化成杂志级质量的信息图,导出300dpi的PNG"

Critique

评审

"Critique this design file across all 5 dimensions and give me a fix list"
"从所有5个维度评审这个设计文件,并给出修复清单"

Vague request (triggers advisor)

模糊请求(触发顾问模式)

"I need something that looks premium for my fintech app"

---
"我需要为我的金融科技应用打造高端质感的设计"

---

Troubleshooting

故障排除

Agent generates generic purple-gradient AI slop The skill's anti-slop rules are in
SKILL.md
. Make sure
npx skills add
completed — check that
SKILL.md
is referenced in your agent's config. Re-run the install.
Brand colors look wrong The brand asset protocol requires live extraction. Tell the agent: "Re-run the brand asset protocol for [Brand] — download the SVG from their press page and grep the hex values."
MP4 export fails Playwright must be installed:
npx playwright install chromium
. FFmpeg must be on PATH:
brew install ffmpeg
/
apt install ffmpeg
.
PPTX text shows as images not text boxes Use
html2pptx.js
, not screenshot-based export. Check that the slide HTML uses semantic elements (
<h1>
,
<p>
,
<span>
) — the converter maps element types to PPTX object types.
Animation is choppy at 25fps Run the 60fps interpolation step in
convert-formats.sh
. For real-time smoothness, set
requestAnimationFrame
timing in the HTML source and verify the
--fps 60
flag in the render call.
Tweaks panel doesn't persist across sessions The panel uses
localStorage
. Verify the HTML is served from the same origin across sessions —
file://
paths that differ by absolute path will miss the stored values. Use a local dev server:
npx serve .

Agent生成了通用的紫色渐变AI劣质设计 技能的反劣质设计规则存于
SKILL.md
中。确保
npx skills add
执行完成——检查你的Agent配置中是否引用了
SKILL.md
。重新运行安装命令。
品牌颜色显示错误 品牌资产协议要求实时提取。告知Agent:“为[品牌]重新执行品牌资产协议——从其新闻页面下载SVG文件并提取十六进制颜色值。”
MP4导出失败 必须安装Playwright:
npx playwright install chromium
。FFmpeg必须在PATH中:
brew install ffmpeg
/
apt install ffmpeg
PPTX文本显示为图片而非文本框 使用
html2pptx.js
,而非基于截图的导出方式。确保幻灯片HTML使用语义化元素(
<h1>
<p>
<span>
)——转换器会将元素类型映射为PPTX对象类型。
25fps动画卡顿 运行
convert-formats.sh
中的60fps插值步骤。如需实时流畅,在HTML源中设置
requestAnimationFrame
计时,并在渲染调用中验证
--fps 60
参数。
调整面板无法跨会话持久化设置 面板使用
localStorage
。验证HTML在跨会话中是否从同一源加载——不同绝对路径的
file://
路径会无法读取存储的值。使用本地开发服务器:
npx serve .

Design Philosophies Quick Reference

设计理念速查

20 philosophies live in
references/design-styles.md
. A fast selection guide:
GoalReach for
Corporate trust / enterpriseIBM Carbon, Swiss Grid, Material Design
Consumer delight / warmthMemphis Color, Bauhaus Utility, Art Nouveau Revival
Tech credibility / startupNeumorphism (refined), Cyberpunk Neon (restrained), Brutalist Raw
Editorial / mediaSwiss Grid, Maximalist Baroque, Wabi-Sabi
Luxury / premiumDieter Rams Reduction, Japanese Minimalism, Art Deco Revival
Always pick directions from different schools to give the client a genuine choice.

20种理念存于
references/design-styles.md
中。快速选择指南:
目标推荐理念
企业信任/企业级IBM Carbon、瑞士网格、Material Design
消费者愉悦/温暖感孟菲斯色彩、包豪斯实用主义、新艺术复兴
技术可信度/初创企业新拟态(优化版)、赛博朋克霓虹(克制版)、粗野主义原始风格
编辑/媒体瑞士网格、极繁主义巴洛克、侘寂
奢华/高端迪特·拉姆斯简约、日式极简、装饰艺术复兴
务必从不同流派中选择方向,为客户提供真正的选择空间。

Key Constraints

关键限制

  • No layer-editable PPTX-to-Figma round-trip
  • No 3D, physics simulation, or particle systems
  • Completely blank-brand designs land at ~60–65/100; provide any brand asset to push toward 80+
  • MP4 export requires local Playwright + FFmpeg
  • 不支持可分层编辑的PPTX转Figma往返流程
  • 不支持3D、物理模拟或粒子系统
  • 完全无品牌设计得分约为60–65/100;提供任何品牌资产可将得分提升至80+
  • MP4导出需要本地安装Playwright + FFmpeg