前端设计
本技能指南用于创建独特的、生产级的前端界面,避免千篇一律的"AI 风格"审美。实现真正可运行的代码,对审美细节和创意选择给予极高关注。
用户提供前端需求:一个组件、页面、应用或界面。他们可能会提供关于用途、受众或技术约束的上下文信息。
设计思维
在编码之前,理解上下文并确定一个大胆的审美方向:
- 用途:这个界面解决什么问题?谁在使用它?
- 基调:选择一个极端风格:极简粗暴、极繁主义混乱、复古未来主义、有机/自然、奢华/精致、趣味/玩具风、编辑/杂志风、粗野主义/原始、装饰艺术/几何、柔和/粉彩、工业/实用主义等。风格种类繁多,以上仅供灵感参考,但最终设计应忠于所选的审美方向。
- 约束:技术要求(框架、性能、无障碍性)。
- 差异化:什么让它令人难忘?用户会记住的那一个亮点是什么?
关键原则:选择一个明确的概念方向并精准执行。大胆的极繁主义和精致的极简主义都能成功——关键在于意图性,而非强度。
然后实现可运行的代码(HTML/CSS/JS、React、Vue 等),需满足:
- 生产级且功能完整
- 视觉上引人注目且令人难忘
- 具有清晰审美观点的整体一致性
- 每个细节都精心打磨
前端审美指南
重点关注:
- 字体排印:选择美观、独特且有趣的字体。避免使用 Arial、Inter 等通用字体;转而选择能提升前端审美的独特字体——出人意料的、有个性的字体选择。将一个独特的展示字体与一个精致的正文字体进行搭配。
- 色彩与主题:确定一个统一的审美风格。使用 CSS 变量保持一致性。以主色调搭配鲜明强调色的方案,远胜于畏缩的、均匀分布的色板。
- 动效:使用动画实现效果和微交互。HTML 优先使用纯 CSS 方案。React 可用时使用 Motion 库(动画使用
anime.js,参见下方 Anime.js v4 参考)。聚焦高影响力时刻:一个精心编排的页面加载配合交错展现(animation-delay),比零散的微交互更令人愉悦。使用滚动触发和令人惊喜的悬停状态。 - 空间构成:意想不到的布局。不对称性。重叠。对角线流动。打破网格的元素。慷慨的留白或有控制的密度。
- 背景与视觉细节:营造氛围和层次感,而非默认使用纯色。添加与整体审美匹配的语境化效果和纹理。运用创意形式,如渐变网格、噪点纹理、几何图案、分层透明度、戏剧性阴影、装饰性边框、自定义光标和颗粒叠加。
绝不使用通用的 AI 生成审美,例如过度使用的字体系列(Inter、Roboto、Arial、系统字体)、老套的配色方案(特别是白色背景上的紫色渐变)、可预测的布局和组件模式,以及缺乏特定上下文个性的千篇一律的设计。
创造性地诠释,做出出乎意料的选择,让设计真正为上下文量身定制。每个设计都不应相同。在浅色和深色主题、不同字体、不同审美风格之间变化。绝不在不同生成之间趋同于常见选择(例如 Space Grotesk)。
重要提示:实现复杂度应匹配审美愿景。极繁主义设计需要精心编写的代码,包含大量动画和效果。极简主义或精致的设计需要克制、精确,以及对间距、字体排印和微妙细节的仔细关注。优雅来自于对愿景的出色执行。
记住:Claude 具备非凡的创造力。不要退缩——展示在跳出框架思考并全力投入独特愿景时能够真正创造的作品。
Anime.js v4 参考指南
严重警告:务必使用 Anime.js v4 语法
本项目使用 Anime.js v4.x.x——在任何情况下都不要使用 v3 语法
如果你准备写 import anime from 'animejs'——停下!
那是 v3。本项目使用 v4。请使用以下正确的导入方式。
快速开始 - 基本设置
1. 正确的 v4 导入(必须)
// 正确的 v4 导入方式
import { animate, createTimeline, stagger, utils, svg, eases, engine } from 'animejs';
// 错误的 v3 导入方式 - 绝不使用
// import anime from 'animejs';
2. 配置时间单位为秒(仅在应用入口设置一次)
// 重要:仅在应用主入口文件设置一次
// React: App.js/App.tsx 或 index.js/index.tsx
// Vue: main.js/main.ts
// 原生 JS: 最先加载的主脚本文件
import { engine } from 'animejs';
// 仅在应用入口设置,不要在组件中设置
engine.timeUnit = 's';
// 现在所有时长都使用秒:1 = 1秒, 0.5 = 500ms
// 不要在单个组件中设置——这是全局设置!
3. 简单动画使用单行格式(必须)
// 好 - 简洁、可读、一行搞定
animate('.element', { x: 250, duration: 1, ease: 'outQuad' });
// 差 - 简单动画不必多行
animate('.element', {
x: 250,
duration: 1,
ease: 'outQuad'
});
验证清单
生成 anime.js 代码前,确认:
- 使用
import { animate, ... } from 'animejs'而非import anime -
engine.timeUnit = 's'仅在应用入口设置一次(不在组件中) - 所有时长使用秒(1 = 1秒)
- 简单动画写在一行
- 使用
animate()而非anime() - 使用
createTimeline()而非anime.timeline() - 使用
ease:而非easing: - 值使用
to:,而非value: - 回调使用
on前缀(onUpdate、onComplete) - 使用
loop和alternate,而非direction - 使用正确的 v4 stagger 语法
stagger() - 尽可能使用简写属性(x、y、z)
核心 API - 最常用模式
基础动画(简单动画单行写法)
// 简单补间 - 始终一行
animate('.element', { x: 250, rotate: 180, duration: 0.8, ease: 'inOutQuad' });
// 淡入 - 一行
animate('.element', { opacity: [0, 1], y: [20, 0], duration: 0.6, ease: 'outQuad' });
// 弹性缩放 - 一行
animate('.element', { scale: [0, 1], duration: 0.8, ease: 'outElastic(1, 0.5)' });
// 无限循环 - 一行
animate('.element', { rotate: 360, duration: 2, loop: true, ease: 'linear' });
时间线创建
const tl = createTimeline({ defaults: { duration: 1, ease: 'outQuad' } });
tl.add('.element1', { x: 250 })
.add('.element2', { y: 100 }, '+=0.2') // 在前一个动画结束0.2秒后
.add('.element3', { rotate: 180 }, '<'); // 与前一个动画同时开始
交错动画(单行写法)
animate('.elements', { x: 250, delay: stagger(0.1) }); // 每个元素间隔0.1秒
animate('.elements', { x: 250, delay: stagger(0.1, { from: 'center' }) });
常见 AI 错误示例
错误 #1:使用 v3 导入模式
// 错误 - 这是 v3
import anime from 'animejs';
anime({ targets: '.element', translateX: 250 });
// 正确 - 始终使用 v4
import { animate } from 'animejs';
animate('.element', { x: 250 });
错误 #2:使用 'targets' 属性
// 错误 - 'targets' 是 v3 语法
animate({ targets: '.element', translateX: 250 });
// 正确 - 第一个参数就是目标
animate('.element', { x: 250 });
错误 #3:使用 'easing' 而非 'ease'
// 错误
animate('.element', { x: 250, easing: 'easeInOutQuad' });
// 正确
animate('.element', { x: 250, ease: 'inOutQuad' });
错误 #4:使用 'value' 设置动画值
// 错误 - 'value' 是 v3 语法
animate('.element', { x: { value: 250 } });
// 正确 - 使用 'to' 设置值
animate('.element', { x: { to: 250 } });
错误 #5:时间线语法错误
// 错误 - anime.timeline() 是 v3 语法
const tl = anime.timeline();
// 正确 - 使用 createTimeline
import { createTimeline } from 'animejs';
const tl = createTimeline();
属性语法参考(v3 -> v4)
缓动函数
// v4:使用 'ease'(不带 'ease' 前缀)
{ ease: 'inOutQuad' }
{ ease: 'outElastic(1, 0.5)' }
{ ease: 'cubicBezier(0.4, 0, 0.2, 1)' }
// v3:不要使用 'easing' 或 'ease' 前缀
// { easing: 'easeInOutQuad' }
方向与循环
// v4
{
loop: true, // 无限循环
loop: 3, // 循环3次
alternate: true, // 交替方向
reversed: true // 反向播放
}
// v3:不要使用 'direction'
// { direction: 'alternate' }
变换属性(优先使用简写)
// v4 两种写法都有效:
animate('.element', { x: 100, y: 50, z: 25 }); // 简写(推荐)
animate('.element', { translateX: 100, translateY: 50, translateZ: 25 }); // 完整写法
回调(全部使用 'on' 前缀)
// v4:简单回调 - 保持一行
animate('.element', { x: 250, duration: 1, onComplete: () => console.log('完成!') });
// v4:多个回调 - 使用多行
animate('.element', {
x: 250,
duration: 1,
onBegin: (anim) => console.log('开始'),
onUpdate: (anim) => console.log('进度:', anim.progress),
onComplete: (anim) => console.log('结束')
});
// v3:不要使用无前缀的回调
// { update: () => {}, complete: () => {} }
常见动画模式
悬停动画(每个动画一行)
element.addEventListener('mouseenter', () => animate(element, { scale: 1.1, duration: 0.3, ease: 'outQuad' }));
element.addEventListener('mouseleave', () => animate(element, { scale: 1, duration: 0.3, ease: 'outQuad' }));
顺序时间线
const tl = createTimeline({ defaults: { duration: 0.5 } });
tl.add('.step1', { x: 100 })
.add('.step2', { y: 100 })
.add('.step3', { scale: 2 });
滚动触发动画
import { createScrollObserver } from 'animejs';
createScrollObserver({
target: '.scroll-element',
root: document.querySelector('.scroll-container'),
play: () => animate('.element', { x: 250, duration: 1 }),
visibility: 0.5
});
高级功能
SVG 动画
import { animate, svg } from 'animejs';
// 路径变形(单行)
animate('#path1', { d: svg.morphTo('#path2'), duration: 1 });
// 绘制 SVG 线条
const drawable = svg.createDrawable('.svg-path');
animate(drawable, { draw: '0% 100%', duration: 2 });
// 运动路径(简单用法单行)
const motionPath = svg.createMotionPath('#motion-path');
animate('.element', { x: motionPath.translateX, y: motionPath.translateY, rotate: motionPath.rotate });
工具函数
import { utils } from 'animejs';
// DOM 选择
const elements = utils.$('.elements');
// 获取当前值
const currentX = utils.get('.element', 'translateX');
// 立即设置值
utils.set('.element', { x: 100, opacity: 0.5 });
// 移除动画
utils.remove('.element');
// 数学工具
utils.random(0, 100);
utils.shuffle([1, 2, 3, 4]);
utils.lerp(0, 100, 0.5); // 50
utils.clamp(150, 0, 100); // 100
性能提示
使用变换属性而非位置属性
// 好 - 使用 transform animate('.element', { x: 100 }); // 差 - 触发重排 animate('.element', { left: 100 });将动画批量放入时间线
// 好 - 单个时间线 const tl = createTimeline(); elements.forEach(el => tl.add(el, { x: 100 })); // 差 - 多个独立动画 elements.forEach(el => animate(el, { x: 100 }));对复杂动画使用 will-change CSS 属性
.animated-element { will-change: transform, opacity; }
AI 代码生成规则
生成 anime.js 动画代码时:
- 仅在应用主入口文件设置
engine.timeUnit = 's'(绝不在组件中) - 始终使用秒作为时长单位(1 = 1秒)
- 始终将简单动画写在一行
- 始终使用 v4 导入方式
- 绝不使用
anime()函数 - 始终使用
animate()做动画 - 绝不使用
targets属性 - 始终使用
ease而非easing - 绝不使用
value,改用to - 始终给回调加
on前缀 - 绝不使用
direction,改用alternate和reversed - 始终使用
createTimeline()创建时间线 - 优先使用简写(
x)而非完整写法(translateX) - 格式化短动画为单行(4个属性以内)
- 绝不在任何情况下生成 v3 语法