核心设计原则
本文档包含所有输出模式共享的核心设计原则和技术规范。
一、概念聚焦原则
一图一概念
- 每张配图只表达 1-2 个核心概念,避免信息过载
- 视觉突出:用最大的视觉空间展示最重要的信息
- 简化表达:去除所有不必要的装饰和说明性文字
- 直击要点:让观众一眼就能理解核心信息
二、极简设计风格
色彩限制
- 仅使用 1 种主色调(浅蓝、浅绿、浅灰等)
- 避免使用渐变、阴影等复杂效果
⚠️ 背景色强制要求
【前置要求 - 最高优先级】
SVG 画布 必须设置非白色背景色,原因如下:
- 纯白背景(#FFFFFF)导致圆角、边框等视觉元素与背景融为一体,无法区分
- 白色背景与文字内容的对比度不足,视觉层次感差
- 无法体现设计感和专业性
<!-- ❌ 错误:纯白背景,圆角和边框无法显现 -->
<svg viewBox="0 0 800 450">
<rect x="60" y="60" width="680" height="330" rx="12" fill="#FFFFFF" stroke="#E0E0E0"/>
</svg>
<!-- ✅ 正确:浅色背景,元素轮廓清晰可见 -->
<svg viewBox="0 0 800 450">
<rect x="60" y="60" width="680" height="330" rx="12" fill="#F0F4F8" stroke="#D0D8E0"/>
</svg>选择标准:
- 背景色必须在
#F5F5F5~#FAF0E6范围内(米白、浅灰、浅米、浅粉、浅蓝等) - 背景色与画布内容的主色调形成轻微对比
- 避免使用纯白
#FFFFFF作为画布背景
🚫 禁止冗余双层容器
【前置要求 - 最高优先级】
SVG 画布 只允许一层背景色,禁止在背景色之上再套一层白色/半透明容器矩形。
原因:
- 双层容器(背景色 + 内层白底框)是冗余设计,增加视觉噪音
- 内层容器没有承载任何信息,却占据了画面的主要视觉空间
- 内容元素应直接放置在背景色上,通过自身颜色和圆角区分层次
<!-- ❌ 错误:冗余双层容器,内层白底框无意义 -->
<svg viewBox="0 0 800 450">
<rect x="0" y="0" width="800" height="450" fill="#F0F4F8"/>
<rect x="60" y="60" width="680" height="330" rx="10" fill="rgba(255,255,255,0.7)" stroke="#D0D8E0"/>
<!-- 内容元素... -->
</svg>
<!-- ✅ 正确:单层背景,内容直接放在背景上,背景rect也必须有圆角 -->
<svg viewBox="0 0 800 450">
<rect x="0" y="0" width="800" height="450" rx="10" fill="#F0F4F8"/>
<!-- 内容元素直接放在背景上 -->
</svg>例外:当内容本身需要分区容器时(如三阶段布局中的阶段卡片),允许使用功能性容器,但这些容器是为内容分区服务的,不是为整个画面套一层外壳。
⚠️ 圆角强制要求
【前置要求 - 最高优先级】
所有矩形/圆角矩形元素 必须设置圆角,禁止使用直角:
原因:
- 直角矩形在浅色背景下与背景融为一体,视觉边界不清晰
- 圆角传达亲和感与现代感,与极简设计风格一致
- 圆角矩形作为内容容器时,与背景形成明确的空间层次
<!-- ❌ 错误:直角矩形,圆角和边框无法显现 -->
<rect x="60" y="60" width="680" height="330" fill="#F0F4F8" stroke="#D0D8E0"/>
<!-- 或 -->
<rect x="60" y="60" width="680" height="330" rx="0" fill="#F0F4F8" stroke="#D0D8E0"/>
<!-- ✅ 正确:标准圆角 8-12px -->
<rect x="60" y="60" width="680" height="330" rx="10" fill="#F0F4F8" stroke="#D0D8E0"/>圆角规范:
- 统一使用
rx="10"(圆角值必须显式写出) - 内部元素(如圆形)不需要圆角
文字极简
- 标题 ≤ 6 字
- 无其他文字说明
- 所有文本单行显示
图形极大化
- 用超大尺寸的几何图形、图标、emoji 作为主要视觉元素
- 采用扁平化风格,避免 3D 效果
- 功能性优先:每个元素都必须有明确目的
三、尺寸标准
| 元素类型 | 最小尺寸 | 说明 |
|---|---|---|
| 标题字体 | 48px | 确保手机端清晰可读 |
| 正文字体 | 24px | 增强可读性 |
| emoji 大小 | 100px | 大幅提升,确保情感表达清晰 |
| 方框/容器高度 | 120px | 提供充足的视觉空间 |
| 圆形元素直径 | 150px | 确保圆形图形清晰可辨 |
| 线条粗细 | 4px | 避免线条过细在手机上消失 |
| 画布尺寸 | 800x450 | 16:9 比例,所有元素按比例放大 |
四、布局与边界控制
画布边界约束
- 画布尺寸:800x450px(16:9 比例)
- 安全边界:上下左右各保留 60px 安全边距
- 有效绘制区域:680x330px
- 绝对禁止内容超出画布边界(最高优先级)
内容长度限制
- 标题:最多 6 个中文字符(约 120px 宽度)
- 标签文字:最多 8 个中文字符(约 160px 宽度)
- 超出自动截断:长文本自动添加"..."省略号
- 所有文本单行显示
元素定位规则
- X 坐标范围:60px ≤ x ≤ 740px
- Y 坐标范围:60px ≤ y ≤ 390px
- 元素宽度:自动计算,确保不超出边界
- 居中对齐:以画布中心 400px 为基准
- 大元素优先:主要图形元素占据画面中心位置
防溢出技术实现
- 预计算布局:生成前计算所有元素最终位置
- 边界检查函数:每个元素生成后立即验证边界
- 动态调整机制:检测到溢出时自动缩小元素或减少内容
- 零容忍原则:发现任何溢出立即重新调整
- 安全余量:所有计算增加 15px 安全余量
五、防重叠机制
分层布局规则
- 第一层(顶部):标题区域,占用 y:60-120px
- 第二层(中部):主要图形区域,占用 y:140-320px
- 第三层(底部):标签或小元素区域,占用 y:340-390px
防重叠措施
- 最小间距:任何两个元素之间必须保持至少 20px 间距
- 元素数量限制:每张图最多 2 个主要元素,避免过度拥挤
- 坐标强制验证:每个元素生成后必须计算边界 box 并检测重叠
- 尺寸自动缩减:检测到潜在重叠时,自动将所有元素缩小 5%
- 优先级规则:标题 > 主图形 > 标签
六、配图策略
核心配图原则
最重要:宁可多生成,不要生成太少。
配图密度要求
- 目标生成 10-15 张 配图(根据文章长度调整)
- 每个重要段落或关键概念生成 1 张配图
- 每个二级标题(##)之后至少配 1 张图
配图位置规则
- 每个二级标题(##)之后立即配图(最高优先级)
- 文章引言结束后配 1 张图
- 文章总结/结论之前配 1 张图
- 重要概念转折、对比、因果关系处配图
- 每 2-3 个重要段落后配 1 张图
七、Emoji 使用指南
Emoji 选择
| 使用场景 | 推荐 emoji | 避免使用 |
|---|---|---|
| 人物角色 | 👨💼👩💼👨⚖️👩⚖️👤👥 | 复杂组合 emoji |
| 情感表达 | 😰😫💔✨💪🎯💸🏗️ | 过于小众的 emoji |
| 工具/物品 | 🔧⚖️📋✅❌💡📊 | 含义模糊的 emoji |
Emoji 使用原则
- 避免复杂组合 emoji(如👨👩👧👦)
- 优先使用常见 emoji
- 控制使用数量:每张图 2-5 个 emoji
八、布局类型库
| 布局类型 | 适用场景 | 元素数量 | 视觉特点 |
|---|---|---|---|
| 线性布局 | 流程、步骤、时间线 | 3-5 个 | 简洁清晰,方向性强 |
| 矩阵布局 | 多维对比、分类展示 | 4-9 个 | 结构化强,易于对比 |
| 分层布局 | 层级关系、优先级 | 3-4 层 | 层次分明,上下关系 |
| 环绕布局 | 核心概念 + 相关要素 | 1+4-6 个 | 焦点集中,向心感强 |
| 网状布局 | 复杂关系、相互关联 | 4-6 个 | 关系复杂,网络化 |
| 放射布局 | 从中心发散的概念 | 1+5-8 个 | 扩散感强,动态明显 |
九、背景色策略
⚠️ 背景色选择原则(必读)
背景色是 SVG 配图的 视觉基底,必须满足:
- 非纯白:禁止使用
#FFFFFF作为画布背景 - 有区分度:背景色与内容元素有足够对比度
- 图级差异化:同一篇文章内的每张配图使用 不同背景色,形成视觉节奏感
单图背景色分配规则
同一篇文章内的每张配图使用不同的背景色,通过配图序号分配。
背景色色库(按类别分组,便于根据文章主题选择):
| 类别 | 背景色 | 适用主题 |
|---|---|---|
| 中性灰白系 | #F5F5F5 #F8F9FA #FAFAFA |
通用、工具指南 |
| 暖白系 | #FAF8F5 #FDF8F3 #FFFBF0 |
生活、文化、随笔 |
| 浅米系 | #FAF0E6 #FFF5E6 #F5E6D3 |
法律、金融、正式 |
| 浅蓝灰系 | #F0F4F8 #E8F4F8 #F0F8FF |
科技、AI、数据 |
| 浅绿系 | #E8F5E8 #F0FFF0 #E8F8E8 |
成长、教育、环保 |
| 浅粉系 | #FFF0F5 #FFE4E8 #F8E8E8 |
情感、生活方式 |
| 浅紫系 | #F3E8F8 #F0E8F8 #E8E0F0 |
思考、创意、艺术 |
| 浅蓝系 | #E0F0F8 #D0E8F5 #C0E0F0 |
海洋、航空、物理 |
| 浅黄系 | #FFFBE6 #FFF8DC #FFFFF0 |
阳光、能源、温暖 |
分配算法
同一篇文章内的每张配图使用不同的背景色,确保无重复:
# 从色库中依次选择,确保每张图的背景色都不同
colors = ["#F0F4F8", "#FAF8F5", "#E8F5E8", "#F3E8F8", "#FAF0E6", "#FFF0F5", "#E0F0F8", "#FFFBE6"]
# 生成 N 张配图时,选择前 N 个不同的颜色简化方法(无需代码):
- 从色库中依次选择,确保同一篇文章内所有配图的背景色都不同即可
边框对比度要求
- 边框色与背景色形成轻微对比(边框色略深于背景色 10-20%)
- 示例:背景
#F0F4F8→ 边框#D0D8E0 - 示例:背景
#FAF8F5→ 边框#E0D8C8
十、兼容性踩坑记录
🚫 禁止使用:SVG Filter
问题描述:在 SVG 中使用 <g filter="url(#shadow)"> 添加阴影效果时,SMIL 动画(animateTransform、animate)在微信 WebView 中无法正常显示。
原因分析:filter 会在 SVG 中创建一个隔离的渲染层(filter region),与 WeChat WebView 的 SMIL 动画渲染引擎存在兼容性问题。
错误示例:
<g filter="url(#shadow)">
<rect ...>
<animateTransform attributeName="transform" type="translate" .../>
</rect>
</g>正确做法:
- ❌ 不要使用
<g filter="url(#shadow)">或任何 filter 效果 - ✅ 使用
<g transform="translate(x, y)">进行定位 - ✅ 动画直接应用在目标元素上,不要被 filter 包裹
视觉替代方案:
- 阴影效果 vs 扁平设计 → 选择扁平设计(符合极简原则)
- 如必须体现层次感 → 使用不同颜色区分,而非阴影
⚠️ 渐变填充 + 动画组合
问题描述:当 fill="url(#gradient)" 和 <animateTransform> 在同一个 <rect> 元素上时,渐变在微信 WebView 中无法显示。
原因分析:渐变渲染和 SMIL 动画在同一个元素的坐标系中存在冲突。
错误示例:
<!-- ❌ 错误:动画和渐变都在同一个 rect 上 -->
<rect fill="url(#gradient)" ...>
<animateTransform attributeName="transform" .../>
</rect>替代方案(推荐):
- 直接使用纯色填充,配合极简设计原则
- 如需渐变效果,使用不带动画的静态元素
🚫 禁止使用:所有渐变填充
问题描述:在公众号中,即使是静态的渐变背景也无法渲染。
原因分析:公众号 WebView 对 SVG 渐变的支持非常有限,无论是否带动画。
错误示例:
<!-- 背景渐变 -->
<linearGradient id="bgGrad">...</linearGradient>
<rect fill="url(#bgGrad)"/>
<!-- 元素渐变 -->
<linearGradient id="stepGrad">...</linearGradient>
<path fill="url(#stepGrad)"/>正确做法:
- 所有渐变都改为纯色
- 背景使用:
#f8f9fa、#f0f4f8等浅色 - 元素使用对应的主色调纯色
📋 公众号 SVG 兼容性汇总(实测)
| 测试用例 | 结果 | 说明 |
|---|---|---|
| 纯色 + 动画 | ✅ 正常 | 测试1、14、15 |
| 虚线流动动画 | ✅ 正常 | 测试5 |
| 箭头绘制动画 | ✅ 正常 | 测试6 |
| Emoji 浮动动画 | ✅ 正常 | 测试9 |
| 脉冲动画 | ✅ 正常 | 测试11 |
| 复杂布局 | ✅ 正常 | 测试13 |
| 渐变背景(无动画) | ❌ 失效 | 测试2、8 |
| 渐变 + 动画(同元素) | ❌ 失效 | 测试3 |
| SVG Filter + 动画 | ❌ 失效 | 测试4 |
| 分离动画和渐变 | ❌ 失效 | 测试10 |
| 纯色 + Filter(无动画) | ❌ 失效 | 测试12 |
结论:
| 特性 | 公众号支持 | 备注 |
|---|---|---|
| 纯色填充 | ✅ 支持 | 推荐使用 |
| SMIL 动画 | ✅ 支持 | 在无 filter/渐变时正常 |
| SVG Filter | ❌ 不支持 | 任何情况都不支持 |
| 渐变填充 | ❌ 不支持 | 任何情况都不支持 |
最佳实践:
- ❌ 禁止使用
<filter>元素 - ❌ 禁止使用
<linearGradient>/fill="url(#gradient)" - ✅ 所有颜色使用纯色(如
#10B981、#f8f9fa) - ✅ 动画使用
<animateTransform>或<animate> - ✅ 元素定位使用
transform="translate(x, y)"
🚨 最高频错误:transform + animateTransform translate 冲突
问题描述:当外层使用 transform="translate(x,y)" 定位,内层又使用 <animateTransform type="translate"> 做浮动动画时,动画会完全覆盖外层的定位,导致所有元素堆叠到左上角 (0,0)。
错误示例:
<!-- ❌ 错误:translate 定位 + translate 动画 = 元素飞到左上角 -->
<g transform="translate(180, 200)">
<circle cx="0" cy="0" r="80" fill="#4A90E2"/>
<animateTransform type="translate" values="0,0; 0,-12; 0,0"/>
</g>正确做法:
<!-- ✅ 正确方法1:直接用 cx/cy 定位,内层包一层做动画 -->
<g>
<circle cx="180" cy="200" r="80" fill="#4A90E2"/>
<g>
<animateTransform type="translate" values="0,0; 0,-12; 0,0"/>
</g>
</g>
<!-- ✅ 正确方法2:translate 定位 + scale 动画(不冲突) -->
<g transform="translate(180, 200)">
<circle cx="0" cy="0" r="80" fill="#4A90E2"/>
<animateTransform type="scale" values="1; 1.1; 1"/>
</g>核心原则:
| 定位方式 | 可用动画类型 | 是否安全 |
|---|---|---|
transform="translate()" |
type="scale" |
✅ 安全 |
transform="translate()" |
type="rotate" |
✅ 安全 |
transform="translate()" |
type="translate" |
❌ 禁止! |
cx/cy 或 x/y 直接定位 |
type="translate" |
✅ 安全 |
记忆口诀:translate 定位只能配 scale/rotate,要做浮动必须用 x/y/cx/cy 直接定位!