欢迎光临
我们一直在努力

AI 辅助设计系统:从品牌 DNA 到组件库的自动生成流水线

AI 辅助设计系统:从品牌 DNA 到组件库的自动生成流水线

一、当我们说"设计系统"时,AI 应该替我们做什么

设计系统的搭建,传统上是一个"从设计师大脑到 Sketch/Figma 再到前端代码"的漫长翻译过程。品牌色、字体阶梯、圆角系列、间距标尺、阴影层级——这些参数的确定,本质上是一系列重复性极高的决策。一个熟练的设计师大概需要 2-3 周来搭建一套中等规模的设计系统基础骨架,而其中至少 60% 的时间花在了"把主色推导出 10 级色阶"、"计算在不同背景下文字色与背景色的 WCAG 对比度"这类可以通过算法完成的工作上。

AI 辅助设计系统要做的事情,不是我教你配色,而是你把品牌主色和一段品牌描述给我,我帮你把色阶、字体、间距、圆角、阴影、动效参数全部推导出来,并且生成可直接接入 Tailwind/Token 体系的 JSON。

这篇文章,我会从算法推导和工程落地两个维度,拆解一个 AI 驱动的设计系统自动生成流水线。

二、算法架构:从品牌关键词到设计 Token 的映射管道

主色到 10 级色阶的算法

品牌主色通常只是一个 Hex 值(比如 #3B82F6),但实际 UI 需要至少 10 级明度梯度。传统做法是设计师手动在 Figma 里调滑块,而本质上这是一个 HSL 空间的亮度插值问题。

核心思路:将主色转为 HSL,固定 H(色相)和 S(饱和度),对 L(亮度)做非线性插值:

L(n) = L_base × f(n/10) (n = 0..9)

其中 f(x) 是一个 S 形曲线函数:
– 浅色端(50-100级):变化剧烈,因为 UI 中浅色背景对亮度敏感
– 深色端(0-50级):变化平缓,避免暗色过于接近黑色

具体参数:

色阶级别亮度系数典型用途
50 L_base × 2.2 极浅背景、卡片底色
100 L_base × 1.8 浅色背景
200 L_base × 1.5 悬停态背景
300 L_base × 1.25 边框色、分割线
400 L_base × 1.1 禁用态文字
500 L_base × 1.0 主色基准
600 L_base × 0.85 悬停态主色
700 L_base × 0.7 按压态主色
800 L_base × 0.5 深色背景上的文字
900 L_base × 0.35 最深强调色

但这里有一个关键细节——单纯修改 L 值会破坏色彩感知一致性。受 Munsell 色彩体系启发,我们还需要做饱和度补偿:当 L 降低时适当提升 S,当 L 升高时适当降低 S,以补偿人眼在不同亮度下对色彩饱和度的感知差异。

字体阶梯的 Modular Scale 自动选择

不同品牌调性对应不同的字体比例系数:

  • 科技/工具型(关键词:高效、专业、精确)→ Major Third (1.25),字阶紧凑,信息密度高
  • 消费/零售型(关键词:温暖、亲切、生活)→ Perfect Fourth (1.333),字阶舒展,呼吸感强
  • 奢侈/高端型(关键词:优雅、精致、克制)→ Augmented Fourth (1.414),字阶跃迁明显,留白多

AI 的做法是:对品牌描述做语义向量化,与三种预设风格的描述做余弦相似度计算,选择最匹配的 Modular Scale 比例。

三、代码实现:一个完整的 Token 生成引擎

/**
* AI 设计系统 Token 生成引擎
*/

/** 品牌输入 */
interface BrandInput {
/** 品牌主色 */
primaryColor: string; // Hex, 如 '#3B82F6'
/** 品牌描述 */
description: string;
/** 品牌关键词 */
keywords: string[];
/** 目标平台 */
platforms: ('web' | 'mobile' | 'flutter')[];
}

/** 色阶生成 */
interface ColorScale {
50: string;
100: string;
200: string;
300: string;
400: string;
500: string;
600: string;
700: string;
800: string;
900: string;
}

class DesignTokenGenerator {
/** 主色 → 10级色阶 */
generateColorScale(hex: string): ColorScale {
const { h, s, l } = this.hexToHSL(hex);

const luminanceCoefficients = [2.2, 1.8, 1.5, 1.25, 1.1, 1.0, 0.85, 0.7, 0.5, 0.35];
const saturationCompensation = [-0.15, -0.1, -0.05, -0.02, 0, 0, 0.02, 0.05, 0.08, 0.1];

const scale: any = {};
const levels = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];

levels.forEach((level, i) => {
const adjustedL = Math.min(100, Math.max(0, l * luminanceCoefficients[i]));
const adjustedS = Math.min(100, Math.max(0, s * (1 + saturationCompensation[i])));
scale[level] = this.hslToHex(h, adjustedS, adjustedL);
});

return scale as ColorScale;
}

/** 根据品牌描述选择最佳 Modular Scale */
selectTypeScale(description: string): number {
const styles = [
{ ratio: 1.25, keywords: ['高效', '专业', '工具', '开发', '企业'] },
{ ratio: 1.333, keywords: ['温暖', '消费', '生活', '社交', '内容'] },
{ ratio: 1.414, keywords: ['优雅', '高端', '奢侈', '设计', '艺术'] },
];

// 计算描述与各风格的关键词匹配度
const scores = styles.map(s => ({
ratio: s.ratio,
score: s.keywords.filter(k => description.includes(k)).length
}));

return scores.sort((a, b) => b.score – a.score)[0].ratio;
}

/** 生成间距标尺 */
generateSpacingScale(density: 'compact' | 'default' | 'comfortable'): Record<string, string> {
const baseMap = {
compact: { base: 4, steps: [1, 2, 3, 4, 5, 6, 8, 10, 12] },
default: { base: 4, steps: [1, 2, 3, 4, 6, 8, 12, 16, 20] },
comfortable: { base: 4, steps: [2, 4, 6, 8, 12, 16, 20, 28, 36] },
};

const config = baseMap[density];
const tokens: Record<string, string> = {};

config.steps.forEach((step, i) => {
tokens[`spacing-${i + 1}`] = `${step * config.base}px`;
});

// 同时生成 rem 版本
config.steps.forEach((step, i) => {
tokens[`spacing-${i + 1}-rem`] = `${((step * config.base) / 16).toFixed(2)}rem`;
});

return tokens;
}

/** 根据品牌调性生成圆角系列 */
generateRadiusScale(style: string): Record<string, string> {
if (style.includes('圆润') || style.includes('可爱')) {
return { sm: '4px', md: '8px', lg: '16px', xl: '24px', full: '9999px' };
}
if (style.includes('锋利') || style.includes('专业')) {
return { sm: '2px', md: '4px', lg: '6px', xl: '8px', full: '9999px' };
}
// 默认:中性
return { sm: '3px', md: '6px', lg: '12px', xl: '18px', full: '9999px' };
}

/** 主入口:从品牌输入生成完整 Token Map */
async generate(input: BrandInput) {
const colorScale = this.generateColorScale(input.primaryColor);
const typeScale = this.selectTypeScale(input.description);

// 通过 AI 语义分析确定密度
const density = input.keywords.includes('高效') ? 'compact' : 'default';
const spacing = this.generateSpacingScale(density);
const radius = this.generateRadiusScale(input.description);

return {
colors: {
primary: colorScale,
// 自动生成语义色
success: this.generateColorScale('#10B981'),
warning: this.generateColorScale('#F59E0B'),
error: this.generateColorScale('#EF4444'),
},
typography: {
scale: typeScale,
// 自动生成字体大小梯度
sizes: this.generateFontSizes(typeScale),
},
spacing,
radius,
};
}

private hexToHSL(hex: string) {
let r = 0, g = 0, b = 0;
hex = hex.replace('#', '');
r = parseInt(hex.substring(0, 2), 16) / 255;
g = parseInt(hex.substring(2, 4), 16) / 255;
b = parseInt(hex.substring(4, 6), 16) / 255;

const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h = 0, s = 0, l = (max + min) / 2;

if (max !== min) {
const d = max – min;
s = l > 0.5 ? d / (2 – max – min) : d / (max + min);
switch (max) {
case r: h = ((g – b) / d + (g < b ? 6 : 0)) / 6; break;
case g: h = ((b – r) / d + 2) / 6; break;
case b: h = ((r – g) / d + 4) / 6; break;
}
}

return { h: h * 360, s: s * 100, l: l * 100 };
}

private hslToHex(h: number, s: number, l: number): string {
s /= 100;
l /= 100;
const a = s * Math.min(l, 1 – l);
const f = (n: number) => {
const k = (n + h / 30) % 12;
const color = l – a * Math.max(Math.min(k – 3, 9 – k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return `#${f(0)}${f(8)}${f(4)}`;
}

private generateFontSizes(scale: number): Record<string, string> {
const base = 16; // 16px base
return {
'xs': `${(base / Math.pow(scale, 2)).toFixed(0)}px`,
'sm': `${(base / scale).toFixed(0)}px`,
'base': `${base}px`,
'lg': `${(base * scale).toFixed(0)}px`,
'xl': `${(base * scale * scale).toFixed(0)}px`,
'2xl': `${(base * Math.pow(scale, 3)).toFixed(0)}px`,
'3xl': `${(base * Math.pow(scale, 4)).toFixed(0)}px`,
};
}
}

四、边界与权衡:AI 生成的设计系统什么时候会"翻车"

三个关键的局限性:

  • 品牌色阶的 HSL 局限:HSL 空间中的亮度插值在某些色相区间会产生"脏色"——比如在黄色区域(H≈60),单纯降低 L 会让颜色变成泥黄色。解决方案是在 L 降低时同步旋转 H 值(向橙色偏移约 5-8°),但这就是一个需要设计师介入的主观决策了。

  • 字体比例不是纯数学问题:同一个 1.25 的 Major Third 比例,在中文字体和英文字体下的视觉效果完全不同。中文笔画密度高,需要更大的字阶跃迁才能产生层次感。AI 需要额外检测目标语言的字符集特征。

  • 圆角和阴影不是可互换的:一个圆角为 8px 的按钮,阴影参数应该和圆角为 2px 的按钮不同。这些跨 Token 的依赖关系,目前的 AI 系统还很难自动推导。

  • 建议的工作流:AI 生成作为"初稿",产出 80% 的正确率,剩下的 20%(色彩微调、跨平台适配、品牌规范性检查)由设计师把关。

    五、总结

    AI 辅助设计系统这件事,最核心的价值不是"替代设计师的审美判断",而是"把设计师从可计算的重复劳动中解放出来"。主色到 10 级色阶、字体阶梯的 Modular Scale 选择、间距和圆角系统的生成——这些都是有明确算法可循的设计决策,AI 可以做得又快又好。真正的难点在于那些跨 Token 的依赖关系和色彩感知的主观判断——这恰好是设计师不可替代的部分。一个好的 AI 设计工具,应该成为设计师的"色彩助手"和"参数计算器",而不是试图成为设计师的替代品。


    作者:李慕杰(Leo / 8limujie)一个相信好设计可以参数化、但永远需要人的温度的前端匠人

    赞(0)
    未经允许不得转载:171主机测评 » AI 辅助设计系统:从品牌 DNA 到组件库的自动生成流水线
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址