Anime.js 超级炫酷的网页动画库详解

简介

Anime.js 是一个轻量级的 JavaScript 动画库,它提供了简单而强大的 API 来创建各种复杂的动画效果。以下是 Anime.js 的主要使用方法和特性:

安装

npm install animejs

示例

基本用法

import { animate, createScope, createSpring, createDraggable } from "animejs";
import { useEffect, useRef, useState } from "react";
import reactLogo from "@/assets/react.svg";

export default function App() {
  const scope = useRef(null);
  const [rotations, setRotations] = useState(0);

  useEffect(() => {
    scope.current = createScope({ root }).add((scope) => {
      animate(".logo", {
        scale: [
          { to: 1.25, ease: "inOut(3)", duration: 200 },
          { to: 1, ease: createSpring({ stiffness: 300 }) },
        ],
        loop: true,
        loopDelay: 250,
      });

      createDraggable(".logo", {
        container: [0, 0, 0, 0],
        releaseEase: createSpring({ stiffness: 300 }),
      });

      scope.add("rotateLogo", (i) => {
        animate(".logo", {
          rotate: i * 360,
          ease: "out(4)",
          duration: 2000,
        });
      });
    });
    return () => {
      scope.current.revert();
    };
  }, []);

  const handleClick = () => {
    const i = rotations + 1;
    setRotations(i);
    scope.current.methods.rotateLogo(i);
  };

  return (
    
React logo
); }

定时器(timer)

import { createTimer } from "animejs";
import { useEffect, useRef } from "react";

export default function Timer() {
  const timeRef = useRef(null);
  const countRef = useRef(null);

  useEffect(() => {
    createTimer({
      duration: 1000,
      loop: true,
      frameRate: 30,
      onUpdate: (self) => {
        if (timeRef.current) {
          timeRef.current.innerHTML = self.currentTime;
        }
      },
      onLoop: (self) => {
        if (countRef.current) {
          countRef.current.innerHTML = self._currentIteration;
        }
      },
    });
  }, []);

  return (
    
current time 0
callback fired 0
); }

时间线(timeline)

import { useEffect } from "react";
import { createTimeline } from "animejs";

export default function TimelineDemo() {
  useEffect(() => {
    const tl = createTimeline({ defaults: { duration: 750 } });

    tl.add(".square", { x: "15rem" })
      .add(".circle", { x: "15rem" })
      .add(".triangle", { x: "15rem", rotate: "1turn" });
  }, []);

  return (
    
); }

动画(animate)

import { animate } from "animejs";
import { useRef } from "react";

export default function AnimateDemo() {
  const ref = useRef(null);

  const handleAnimate = () => {
    animate(ref.current, {
      opacity: [0, 1],
      scale: [0.5, 1.2, 1],
      rotate: [0, 360],
      duration: 1200,
      ease: "inOut(3)",
    });
  };

  return (
    
); }

拖动(drag)

import { useEffect, useRef } from "react";
import { createDraggable } from "animejs";

export default function DraggableDemo() {
  const containerRef = useRef(null);

  useEffect(() => {
    if (containerRef.current) {
      createDraggable(".square", {
        container: containerRef.current, // 限定在容器内拖动
        releaseEase: "out(3)",
      });
    }
  }, []);

  return (
    
); }

滚动(scroll)

import { animate } from "animejs";
import { useEffect, useRef } from "react";

export default function ScrollDemo() {
  // 用ref存储动画状态,避免重复渲染
  const lastProgress = useRef(0);
  const ticking = useRef(false);

  useEffect(() => {
    const onScroll = () => {
      if (!ticking.current) {
        window.requestAnimationFrame(() => {
          const scrollY = window.scrollY;
          const docHeight = document.body.scrollHeight - window.innerHeight;
          const progress = Math.min(scrollY / docHeight, 1);

          // 只在进度有明显变化时才触发动画
          if (Math.abs(progress - lastProgress.current) > 0.001) {
            lastProgress.current = progress;

            // 1. 粉色盒子:分段动画
            if (progress < 0.33) {
              // 第一段:下移+放大
              animate(".scroll-box", {
                translateY: progress * 600,
                scale: 1 + progress * 1.5,
                opacity: 1,
                rotate: 0,
                background: "#f472b6",
                duration: 400,
                ease: "out(3)",
              });
            } else if (progress < 0.66) {
              // 第二段:旋转+变色
              animate(".scroll-box", {
                translateY: 200 + (progress - 0.33) * 600,
                scale: 1.5,
                opacity: 1 - (progress - 0.33) * 1.5,
                rotate: (progress - 0.33) * 720,
                background: "#fbbf24",
                duration: 400,
                ease: "inOut(2)",
              });
            } else {
              // 第三段:缩小+淡出
              animate(".scroll-box", {
                translateY: 400 + (progress - 0.66) * 600,
                scale: 1.5 - (progress - 0.66) * 1.5,
                opacity: 0.5 - (progress - 0.66) * 1.5,
                rotate: 360,
                background: "#34d399",
                duration: 400,
                ease: "in(2)",
              });
            }

            // 2. 蓝色盒子:左右来回移动+弹性
            animate(".scroll-box2", {
              translateX: Math.sin(progress * Math.PI * 2) * 300,
              scale: 1 + Math.abs(Math.cos(progress * Math.PI)),
              rotate: progress * 360,
              background: "#60a5fa",
              duration: 500,
              ease: "outElastic(1, .5)",
            });

            // 3. 进度条
            animate(".scroll-progress", {
              scaleX: progress,
              duration: 200,
              ease: "linear",
            });

            // 4. 文字渐显
            animate(".scroll-text", {
              opacity: progress,
              translateY: 100 - progress * 100,
              duration: 400,
              ease: "out(2)",
            });
          }
          ticking.current = false;
        });
        ticking.current = true;
      }
    };

    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    
{/* 滚动进度条 */}
{/* 动画盒子1 */}
{/* 动画盒子2 */}
{/* 渐显文字 */}

分段动画、弹性、渐变、旋转、缩放、透明度,全部联动!

继续滚动,体验更丰富的滚动动画效果。

{/* 内容填充 */}

你可以继续添加更多动画元素,或根据滚动区间分段控制动画效果。

); }

作用域(Scope)

import { useEffect } from "react";
import { animate, utils, createScope } from "animejs";

export default function ScopeDemo() {
  useEffect(() => {
    // 创建 scope,带媒体查询
    const scope = createScope({
      mediaQueries: {
        isSmall: "(max-width: 500px)",
        reduceMotion: "(prefers-reduced-motion)",
      },
    }).add((self) => {
      const { isSmall, reduceMotion } = self.matches;

      // 响应式设置缩放
      if (isSmall) {
        utils.set(".square", { scale: 0.5 });
      } else {
        utils.set(".square", { scale: 1 });
      }

      // 响应式动画
      animate(".square", {
        x: isSmall ? 0 : ["-35vw", "35vw"],
        y: isSmall ? ["-40vh", "40vh"] : 0,
        loop: true,
        alternate: true,
        duration: reduceMotion ? 0 : isSmall ? 750 : 1250,
        easing: "inOutSine",
      });
    });

    // 卸载时清理
    return () => scope.revert();
  }, []);

  return (
    
); }

错峰(Alternate)

import { animate, stagger } from "animejs";
import { useEffect } from "react";

export default function StaggerDemo() {
  useEffect(() => {
    animate(".stagger-item", {
      translateY: [300, 0],
      scale: [0.3, 1],
      rotate: [-90, 0],
      opacity: [0, 1],
      delay: stagger(200),
      duration: 1200,
      ease: "outElastic(1, .5)",
    });
  }, []);

  return (
    
); }

 Anime.js 超级炫酷的网页动画库详解 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿技术分享

你可能感兴趣的:(前端源码分享,javascript,开发语言,ecmascript,anime.js,timeline,animate)