自定义动画曲线的应用

·
次浏览
AI 摘要生成中

下面的自定义 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.js
import 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.js
import 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.ts
import 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.ts
import 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);
 
  1. 质量 (mass):
  2. 刚度 (stiffness):
  3. 阻尼 (damping):

这段代码创建了一个优化的弹簧动画配置,通过调整感知持续时间(perceptualDuration)和反弹程度(bounce)来控制动画的行为。这种方法允许你以更直观的方式定义弹簧动画,而不是直接操作质量、刚度和阻尼这些较为抽象的物理参数。

作者也提供了开发的2个相关工具:CSS Spring Easing Generatortailwind spring plugin


Ease 动画使用场景

  1. ease-in(开始慢,然后加速):

    • 元素离开屏幕或视图
    • 淡出效果
    • 下拉菜单关闭
    • 模态框关闭

    具体曲线选择:

    • quad:适合轻微的加速效果
    • cubic/quart:中等加速效果
    • quint/expo:快速加速效果
    • circ:非常快速的加速,适合戏剧性效果
  2. ease-out(开始快,然后减速):

    • 元素进入屏幕或视图
    • 淡入效果
    • 下拉菜单打开
    • 模态框打开
    • 弹出提示

    具体曲线选择:

    • quad:轻微的减速效果
    • cubic/quart:中等减速效果
    • quint/expo:快速减速效果
    • circ:非常快速的减速,适合戏剧性效果
  3. ease-in-out(开始慢,中间快,结束慢):

    • 元素在屏幕上移动
    • 颜色变化
    • 大小缩放
    • 旋转动画
    • 页面切换过渡

    具体曲线选择:

    • quad:适合轻微的过渡效果
    • cubic/quart:中等强度的过渡效果
    • quint/expo:强烈的过渡效果
    • circ:非常强烈的过渡效果,适合戏剧性的变化

一些具体的应用示例:

  1. 按钮悬停效果:使用 ease-out-quart 可以让按钮快速放大然后缓慢停止。

  2. 页面滚动:使用 ease-in-out-cubic 可以创造出平滑的滚动效果。

  3. 加载动画:使用 ease-in-out-quint 可以为循环动画添加有趣的节奏。

  4. 菜单展开:使用 ease-out-expo 可以让菜单快速展开并在结束时略微减速。

  5. 图片画廊切换:使用 ease-in-out-circ 可以创造出戏剧性的图片切换效果。

  6. 表单验证反馈:使用 ease-in-quad 可以为错误提示添加轻微的进入效果。

  7. 卡片翻转:使用 ease-in-out-cubic 可以创造出自然的翻转动画。

  8. 进度条填充:使用 ease-out-quart 可以让进度条快速开始并逐渐减速。

选择合适的缓动曲线可以大大提升用户界面的感觉和用户体验。根据动画的具体需求和上下文,你可以选择最合适的曲线来实现预期的效果。


Spring 动画使用场景

  1. 页面转场动画
  • 使用 optimizedSoftSpringoptimizedMicroRebound 可以为页面切换提供平滑的过渡效果。
  1. 弹出菜单或模态框
  • optimizedRebound 适合用于菜单或模态框的打开动画,给用户一种轻快的感觉。
  1. 列表项动画
  • 在加载列表时,使用 optimizedMicroDamp 可以让列表项依次滑入,创造出流畅的加载效果。
  1. 按钮反馈
  • 点击按钮时,用 optimizedMicroRebound 制作轻微的按压效果,增强交互感。
  1. 滚动动画
  • 使用 optimizedSoftBounce 可以为滚动到页面顶部或底部时提供柔和的反弹效果。
  1. 展开/折叠动画
  • 对于可折叠的内容面板,optimizedSoftSpring 可以创造出自然的展开和折叠动画。
  1. 拖拽释放效果
  • 在拖拽界面元素后释放时,使用 optimizedRebound 可以提供适度的回弹效果。
  1. 图表动画
  • 在数据可视化中,使用 optimizedMicroDamp 可以让图表元素平滑地进入视图。
  1. 表单验证反馈
  • 当输入无效时,使用 optimizedMicroRebound 可以为输入框添加轻微的抖动效果。
  1. 加载指示器
  • 使用 optimizedSoftBounce 可以创建循环的加载动画,如跳动的圆点。
  1. 卡片堆叠效果
  • 在卡片式界面中,使用 optimizedSoftSpring 可以创建平滑的卡片切换动画。
  1. 悬停效果
  • 为按钮或卡片添加悬停效果时,optimizedMicroRebound 可以创造出轻微的放大或浮起效果。

在使用这些优化后的动画时,可以根据具体需求调整 createOptimizedSpring 函数的参数。例如,如果需要更快或更慢的动画,可以调整 perceptualDuration;如果需要更强或更弱的反弹效果,可以调整 bounce 值。

这些优化后的动画配置不仅可以提高动画的视觉吸引力,还能确保动画在不同设备上的一致性和可预测性。通过精心设计的动画,可以显著提升用户体验,使界面更加生动和易于理解。