下面的自定义 ease 曲线是我在 课程中看到的,由 Animations on the web 制作。如果内置缓和曲线不够强,你可以使用这些曲线。 Benjamin De Cock
结合 Tailwind 使用
globals.css:root { --ease-in-quad: cubic-bezier(.55, .085, .68, .53); --ease-in-cubic: cubic-bezier(.550, .055, .675, .19); --ease-in-quart: cubic-bezier(.895, .03, .685, .22); --ease-in-quint: cubic-bezier(.755, .05, .855, .06); --ease-in-expo: cubic-bezier(.95, .05, .795, .035); --ease-in-circ: cubic-bezier(.6, .04, .98, .335); --ease-out-quad: cubic-bezier(.25, .46, .45, .94); --ease-out-cubic: cubic-bezier(.215, .61, .355, 1); --ease-out-quart: cubic-bezier(.165, .84, .44, 1); --ease-out-quint: cubic-bezier(.23, 1, .32, 1); --ease-out-expo: cubic-bezier(.19, 1, .22, 1); --ease-out-circ: cubic-bezier(.075, .82, .165, 1); --ease-in-out-quad: cubic-bezier(.455, .03, .515, .955); --ease-in-out-cubic: cubic-bezier(.645, .045, .355, 1); --ease-in-out-quart: cubic-bezier(.77, 0, .175, 1); --ease-in-out-quint: cubic-bezier(.86, 0, .07, 1); --ease-in-out-expo: cubic-bezier(1, 0, 0, 1); --ease-in-out-circ: cubic-bezier(.785, .135, .15, .86); }
globals.css:root { --ease-in-quad: cubic-bezier(.55, .085, .68, .53); --ease-in-cubic: cubic-bezier(.550, .055, .675, .19); --ease-in-quart: cubic-bezier(.895, .03, .685, .22); --ease-in-quint: cubic-bezier(.755, .05, .855, .06); --ease-in-expo: cubic-bezier(.95, .05, .795, .035); --ease-in-circ: cubic-bezier(.6, .04, .98, .335); --ease-out-quad: cubic-bezier(.25, .46, .45, .94); --ease-out-cubic: cubic-bezier(.215, .61, .355, 1); --ease-out-quart: cubic-bezier(.165, .84, .44, 1); --ease-out-quint: cubic-bezier(.23, 1, .32, 1); --ease-out-expo: cubic-bezier(.19, 1, .22, 1); --ease-out-circ: cubic-bezier(.075, .82, .165, 1); --ease-in-out-quad: cubic-bezier(.455, .03, .515, .955); --ease-in-out-cubic: cubic-bezier(.645, .045, .355, 1); --ease-in-out-quart: cubic-bezier(.77, 0, .175, 1); --ease-in-out-quint: cubic-bezier(.86, 0, .07, 1); --ease-in-out-expo: cubic-bezier(1, 0, 0, 1); --ease-in-out-circ: cubic-bezier(.785, .135, .15, .86); }
tailwind.config.jsimport typograhpy from '@tailwindcss/typography'; import type { Config } from 'tailwindcss'; export default { content: ['./src/**/*.{ts,tsx}', './data/**/*.{md,mdx}'], theme: { extend: { // ... 其他扩展配置 ... transitionTimingFunction: { 'in-quad': 'var(--ease-in-quad)', 'in-cubic': 'var(--ease-in-cubic)', 'in-quart': 'var(--ease-in-quart)', 'in-quint': 'var(--ease-in-quint)', 'in-expo': 'var(--ease-in-expo)', 'in-circ': 'var(--ease-in-circ)', 'out-quad': 'var(--ease-out-quad)', 'out-cubic': 'var(--ease-out-cubic)', 'out-quart': 'var(--ease-out-quart)', 'out-quint': 'var(--ease-out-quint)', 'out-expo': 'var(--ease-out-expo)', 'out-circ': 'var(--ease-out-circ)', 'in-out-quad': 'var(--ease-in-out-quad)', 'in-out-cubic': 'var(--ease-in-out-cubic)', 'in-out-quart': 'var(--ease-in-out-quart)', 'in-out-quint': 'var(--ease-in-out-quint)', 'in-out-expo': 'var(--ease-in-out-expo)', 'in-out-circ': 'var(--ease-in-out-circ)', }, // ... 其他扩展配置 ... }, }, // ... 其他配置 ... } satisfies Config;
tailwind.config.jsimport typograhpy from '@tailwindcss/typography'; import type { Config } from 'tailwindcss'; export default { content: ['./src/**/*.{ts,tsx}', './data/**/*.{md,mdx}'], theme: { extend: { // ... 其他扩展配置 ... transitionTimingFunction: { 'in-quad': 'var(--ease-in-quad)', 'in-cubic': 'var(--ease-in-cubic)', 'in-quart': 'var(--ease-in-quart)', 'in-quint': 'var(--ease-in-quint)', 'in-expo': 'var(--ease-in-expo)', 'in-circ': 'var(--ease-in-circ)', 'out-quad': 'var(--ease-out-quad)', 'out-cubic': 'var(--ease-out-cubic)', 'out-quart': 'var(--ease-out-quart)', 'out-quint': 'var(--ease-out-quint)', 'out-expo': 'var(--ease-out-expo)', 'out-circ': 'var(--ease-out-circ)', 'in-out-quad': 'var(--ease-in-out-quad)', 'in-out-cubic': 'var(--ease-in-out-cubic)', 'in-out-quart': 'var(--ease-in-out-quart)', 'in-out-quint': 'var(--ease-in-out-quint)', 'in-out-expo': 'var(--ease-in-out-expo)', 'in-out-circ': 'var(--ease-in-out-circ)', }, // ... 其他扩展配置 ... }, }, // ... 其他配置 ... } satisfies Config;
这样配置后,我们就可以在 tsx 文件中使用这些缓动函数了。例如:
<div className="transition-all duration-300 ease-out-quart">
这个 div 将使用 ease-out-quart 缓动函数进行过渡
</div>
<div className="transition-all duration-300 ease-out-quart">
这个 div 将使用 ease-out-quart 缓动函数进行过渡
</div>
结合 Framer Motion 使用
下面代码中的 Spring animations
来自最近很火的 软件仓库,可以在官方的开源代码中找到。 RSSNext/Follow
./components/ui/constants/animation.tsimport type { Spring, Easing } from "motion/react"; // Spring animations export const rebound: Spring = { type: "spring", bounce: 0.25, stiffness: 140, damping: 8, }; export const microDamp: Spring = { type: "spring", damping: 24, }; export const microRebound: Spring = { type: "spring", stiffness: 300, damping: 20, }; export const softSpring: Spring = { type: "spring", stiffness: 120, damping: 20, }; export const softBounce: Spring = { type: "spring", damping: 10, stiffness: 100, }; // Easing functions export const inQuad: Easing = [0.55, 0.085, 0.68, 0.53]; export const inCubic: Easing = [0.55, 0.055, 0.675, 0.19]; export const inQuart: Easing = [0.895, 0.03, 0.685, 0.22]; export const inQuint: Easing = [0.755, 0.05, 0.855, 0.06]; export const inExpo: Easing = [0.95, 0.05, 0.795, 0.035]; export const inCirc: Easing = [0.6, 0.04, 0.98, 0.335]; export const outQuad: Easing = [0.25, 0.46, 0.45, 0.94]; export const outCubic: Easing = [0.215, 0.61, 0.355, 1]; export const outQuart: Easing = [0.165, 0.84, 0.44, 1]; export const outQuint: Easing = [0.23, 1, 0.32, 1]; export const outExpo: Easing = [0.19, 1, 0.22, 1]; export const outCirc: Easing = [0.075, 0.82, 0.165, 1]; export const inOutQuad: Easing = [0.455, 0.03, 0.515, 0.955]; export const inOutCubic: Easing = [0.645, 0.045, 0.355, 1]; export const inOutQuart: Easing = [0.77, 0, 0.175, 1]; export const inOutQuint: Easing = [0.86, 0, 0.07, 1]; export const inOutExpo: Easing = [1, 0, 0, 1]; export const inOutCirc: Easing = [0.785, 0.135, 0.15, 0.86];
./components/ui/constants/animation.tsimport type { Spring, Easing } from "motion/react"; // Spring animations export const rebound: Spring = { type: "spring", bounce: 0.25, stiffness: 140, damping: 8, }; export const microDamp: Spring = { type: "spring", damping: 24, }; export const microRebound: Spring = { type: "spring", stiffness: 300, damping: 20, }; export const softSpring: Spring = { type: "spring", stiffness: 120, damping: 20, }; export const softBounce: Spring = { type: "spring", damping: 10, stiffness: 100, }; // Easing functions export const inQuad: Easing = [0.55, 0.085, 0.68, 0.53]; export const inCubic: Easing = [0.55, 0.055, 0.675, 0.19]; export const inQuart: Easing = [0.895, 0.03, 0.685, 0.22]; export const inQuint: Easing = [0.755, 0.05, 0.855, 0.06]; export const inExpo: Easing = [0.95, 0.05, 0.795, 0.035]; export const inCirc: Easing = [0.6, 0.04, 0.98, 0.335]; export const outQuad: Easing = [0.25, 0.46, 0.45, 0.94]; export const outCubic: Easing = [0.215, 0.61, 0.355, 1]; export const outQuart: Easing = [0.165, 0.84, 0.44, 1]; export const outQuint: Easing = [0.23, 1, 0.32, 1]; export const outExpo: Easing = [0.19, 1, 0.22, 1]; export const outCirc: Easing = [0.075, 0.82, 0.165, 1]; export const inOutQuad: Easing = [0.455, 0.03, 0.515, 0.955]; export const inOutCubic: Easing = [0.645, 0.045, 0.355, 1]; export const inOutQuart: Easing = [0.77, 0, 0.175, 1]; export const inOutQuint: Easing = [0.86, 0, 0.07, 1]; export const inOutExpo: Easing = [1, 0, 0, 1]; export const inOutCirc: Easing = [0.785, 0.135, 0.15, 0.86];
使用示例:
import { motion } from 'motion/react';
import { softSpring, outExpo } from './components/ui/constants/animation';
function AnimatedComponent() {
return (
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={softSpring}
>
Spring Animation
</motion.div>
);
}
function EasingAnimatedComponent() {
return (
<motion.div
initial={{ opacity: 0, x: -50 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, ease: outExpo }}
>
Easing Animation
</motion.div>
);
}
import { motion } from 'motion/react';
import { softSpring, outExpo } from './components/ui/constants/animation';
function AnimatedComponent() {
return (
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={softSpring}
>
Spring Animation
</motion.div>
);
}
function EasingAnimatedComponent() {
return (
<motion.div
initial={{ opacity: 0, x: -50 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, ease: outExpo }}
>
Easing Animation
</motion.div>
);
}
Spring 动画优化
可以对 Spring 动画进行优化,创造出更流畅的动画效果。
在之前的 animation.ts
文件中添加以下代码:
// 新增函数:生成优化的弹簧动画配置
export function createOptimizedSpring(perceptualDuration: number, bounce: number): Spring {
const mass = 1;
const stiffness = Math.pow((2 * Math.PI) / perceptualDuration, 2) * mass;
let damping: number;
if (bounce >= 0) {
damping = ((1 - bounce) * 4 * Math.PI) / perceptualDuration;
} else {
damping = (4 * Math.PI) / (perceptualDuration * (1 + bounce));
}
return {
type: "spring",
mass,
stiffness,
damping,
};
}
// 使用新函数创建优化的弹簧动画
export const optimizedRebound = createOptimizedSpring(0.5, 0.25);
export const optimizedMicroDamp = createOptimizedSpring(0.3, -0.5);
export const optimizedMicroRebound = createOptimizedSpring(0.2, 0.1);
export const optimizedSoftSpring = createOptimizedSpring(0.6, 0);
export const optimizedSoftBounce = createOptimizedSpring(0.8, 0.3);
// 新增函数:生成优化的弹簧动画配置
export function createOptimizedSpring(perceptualDuration: number, bounce: number): Spring {
const mass = 1;
const stiffness = Math.pow((2 * Math.PI) / perceptualDuration, 2) * mass;
let damping: number;
if (bounce >= 0) {
damping = ((1 - bounce) * 4 * Math.PI) / perceptualDuration;
} else {
damping = (4 * Math.PI) / (perceptualDuration * (1 + bounce));
}
return {
type: "spring",
mass,
stiffness,
damping,
};
}
// 使用新函数创建优化的弹簧动画
export const optimizedRebound = createOptimizedSpring(0.5, 0.25);
export const optimizedMicroDamp = createOptimizedSpring(0.3, -0.5);
export const optimizedMicroRebound = createOptimizedSpring(0.2, 0.1);
export const optimizedSoftSpring = createOptimizedSpring(0.6, 0);
export const optimizedSoftBounce = createOptimizedSpring(0.8, 0.3);
- 质量 (mass):
- 刚度 (stiffness):
- 阻尼 (damping):
这段代码创建了一个优化的弹簧动画配置,通过调整感知持续时间(perceptualDuration)和反弹程度(bounce)来控制动画的行为。这种方法允许你以更直观的方式定义弹簧动画,而不是直接操作质量、刚度和阻尼这些较为抽象的物理参数。
作者也提供了开发的2个相关工具: 和 CSS Spring Easing Generator。 tailwind spring plugin
Ease 动画使用场景
-
ease-in(开始慢,然后加速):
- 元素离开屏幕或视图
- 淡出效果
- 下拉菜单关闭
- 模态框关闭
具体曲线选择:
- quad:适合轻微的加速效果
- cubic/quart:中等加速效果
- quint/expo:快速加速效果
- circ:非常快速的加速,适合戏剧性效果
-
ease-out(开始快,然后减速):
- 元素进入屏幕或视图
- 淡入效果
- 下拉菜单打开
- 模态框打开
- 弹出提示
具体曲线选择:
- quad:轻微的减速效果
- cubic/quart:中等减速效果
- quint/expo:快速减速效果
- circ:非常快速的减速,适合戏剧性效果
-
ease-in-out(开始慢,中间快,结束慢):
- 元素在屏幕上移动
- 颜色变化
- 大小缩放
- 旋转动画
- 页面切换过渡
具体曲线选择:
- quad:适合轻微的过渡效果
- cubic/quart:中等强度的过渡效果
- quint/expo:强烈的过渡效果
- circ:非常强烈的过渡效果,适合戏剧性的变化
一些具体的应用示例:
-
按钮悬停效果:使用
ease-out-quart
可以让按钮快速放大然后缓慢停止。 -
页面滚动:使用
ease-in-out-cubic
可以创造出平滑的滚动效果。 -
加载动画:使用
ease-in-out-quint
可以为循环动画添加有趣的节奏。 -
菜单展开:使用
ease-out-expo
可以让菜单快速展开并在结束时略微减速。 -
图片画廊切换:使用
ease-in-out-circ
可以创造出戏剧性的图片切换效果。 -
表单验证反馈:使用
ease-in-quad
可以为错误提示添加轻微的进入效果。 -
卡片翻转:使用
ease-in-out-cubic
可以创造出自然的翻转动画。 -
进度条填充:使用
ease-out-quart
可以让进度条快速开始并逐渐减速。
选择合适的缓动曲线可以大大提升用户界面的感觉和用户体验。根据动画的具体需求和上下文,你可以选择最合适的曲线来实现预期的效果。
Spring 动画使用场景
- 页面转场动画
- 使用
optimizedSoftSpring
或optimizedMicroRebound
可以为页面切换提供平滑的过渡效果。
- 弹出菜单或模态框
optimizedRebound
适合用于菜单或模态框的打开动画,给用户一种轻快的感觉。
- 列表项动画
- 在加载列表时,使用
optimizedMicroDamp
可以让列表项依次滑入,创造出流畅的加载效果。
- 按钮反馈
- 点击按钮时,用
optimizedMicroRebound
制作轻微的按压效果,增强交互感。
- 滚动动画
- 使用
optimizedSoftBounce
可以为滚动到页面顶部或底部时提供柔和的反弹效果。
- 展开/折叠动画
- 对于可折叠的内容面板,
optimizedSoftSpring
可以创造出自然的展开和折叠动画。
- 拖拽释放效果
- 在拖拽界面元素后释放时,使用
optimizedRebound
可以提供适度的回弹效果。
- 图表动画
- 在数据可视化中,使用
optimizedMicroDamp
可以让图表元素平滑地进入视图。
- 表单验证反馈
- 当输入无效时,使用
optimizedMicroRebound
可以为输入框添加轻微的抖动效果。
- 加载指示器
- 使用
optimizedSoftBounce
可以创建循环的加载动画,如跳动的圆点。
- 卡片堆叠效果
- 在卡片式界面中,使用
optimizedSoftSpring
可以创建平滑的卡片切换动画。
- 悬停效果
- 为按钮或卡片添加悬停效果时,
optimizedMicroRebound
可以创造出轻微的放大或浮起效果。
在使用这些优化后的动画时,可以根据具体需求调整 createOptimizedSpring
函数的参数。例如,如果需要更快或更慢的动画,可以调整 perceptualDuration
;如果需要更强或更弱的反弹效果,可以调整 bounce
值。
这些优化后的动画配置不仅可以提高动画的视觉吸引力,还能确保动画在不同设备上的一致性和可预测性。通过精心设计的动画,可以显著提升用户体验,使界面更加生动和易于理解。