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

简介

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

安装

复制代码
npm install animejs

基本用法

复制代码
<script setup>
import { ref, onMounted } from "vue";
import anime from "animejs";

const rotations = ref(0);
const logoRef = ref(null);

const handleClick = () => {
  rotations.value += 1;
  anime({
    targets: logoRef.value,
    rotate: rotations.value * 360,
    easing: "easeOutQuart",
    duration: 2000,
  });
};

onMounted(() => {
  anime({
    targets: logoRef.value,
    scale: [
      { value: 1.25, easing: "easeInOutCubic", duration: 200 },
      { value: 1, easing: "spring(1, 80, 10, 0)" },
    ],
    loop: true,
    direction: "alternate",
    loopDelay: 250,
  });
});
</script>

<template>
  <div class="mt-10">
    <img ref="logoRef" src="@/assets/react.svg" class="logo" alt="React logo" />
    <button
      class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors mt-4"
      @click="handleClick"
    >
      旋转
    </button>
  </div>
</template>

定时器(timer)

复制代码
<script setup>
import { ref, onMounted, onUnmounted } from "vue";

const time = ref(0);
const count = ref(0);
let interval = null;

onMounted(() => {
  let currentIteration = 0;
  interval = setInterval(() => {
    time.value = Date.now();
    currentIteration += 1;
    count.value = currentIteration;
  }, 1000 / 30);
});

onUnmounted(() => {
  clearInterval(interval);
});
</script>

<template>
  <div class="m-10 container mx-auto max-w-2xl">
    <div class="flex flex-row justify-center items-center gap-8">
      <div
        class="relative w-64 h-24 rounded-lg overflow-hidden shadow-lg bg-[#6d402a] flex flex-col items-center justify-center"
      >
        <span class="text-lg text-white mb-2">current time</span>
        <span
          class="text-6xl font-mono font-bold tracking-widest text-[#ffa94d] lcd"
          >{{ time }}</span
        >
      </div>
      <div
        class="relative w-64 h-24 rounded-lg overflow-hidden shadow-lg bg-[#6d402a] flex flex-col items-center justify-center"
      >
        <span class="text-lg text-white mb-2">callback fired</span>
        <span
          class="text-6xl font-mono font-bold tracking-widest text-[#ffa94d] lcd"
          >{{ count }}</span
        >
      </div>
    </div>
  </div>
</template>

时间线(timeline)

复制代码
<script setup>
import { onMounted } from "vue";
import anime from "animejs";

onMounted(() => {
  const tl = anime.timeline({ duration: 750 });
  tl.add({ targets: ".square", translateX: "15rem" })
    .add({ targets: ".circle", translateX: "15rem" })
    .add({ targets: ".triangle", translateX: "15rem", rotate: "1turn" });
});
</script>

<template>
  <div class="flex gap-4 mt-10">
    <div class="square w-16 h-16 bg-red-400 rounded"></div>
    <div class="circle w-16 h-16 bg-green-400 rounded-full"></div>
    <div
      class="triangle"
      style="width: 0; height: 0; border-left: 32px solid transparent; border-right: 32px solid transparent; border-bottom: 64px solid #60a5fa;"
    ></div>
  </div>
</template>

动画(animate)

复制代码
<script setup>
import { ref } from "vue";
import anime from "animejs";

const boxRef = ref(null);

const handleAnimate = () => {
  anime({
    targets: boxRef.value,
    opacity: [0, 1],
    scale: [0.5, 1.2, 1],
    rotate: [0, 360],
    duration: 1200,
    easing: "easeInOutCubic",
  });
};
</script>

<template>
  <div class="mt-10 flex flex-col items-center">
    <div ref="boxRef" class="w-24 h-24 bg-purple-400 rounded mb-4"></div>
    <button
      @click="handleAnimate"
      class="px-4 py-2 bg-purple-600 text-white rounded"
    >
      动画
    </button>
  </div>
</template>

拖动(drag)

复制代码
<script setup>
import { ref, onMounted } from "vue";
import interact from "interactjs";

const containerRef = ref(null);
const squareRef = ref(null);

onMounted(() => {
  interact(squareRef.value).draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: containerRef.value,
        endOnly: true,
      }),
    ],
    listeners: {
      move(event) {
        const target = event.target;
        const x = (parseFloat(target.getAttribute("data-x")) || 0) + event.dx;
        const y = (parseFloat(target.getAttribute("data-y")) || 0) + event.dy;
        target.style.transform = `translate(${x}px, ${y}px)`;
        target.setAttribute("data-x", x);
        target.setAttribute("data-y", y);
      },
    },
  });
});
</script>

<template>
  <div
    ref="containerRef"
    class="mt-10 w-[400px] h-[200px] bg-gray-100 relative flex items-center justify-center"
  >
    <div
      ref="squareRef"
      class="square w-16 h-16 bg-yellow-400 rounded absolute top-0 left-0 cursor-move"
    ></div>
  </div>
</template>

滚动(scroll)

复制代码
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import anime from "animejs";

const lastProgress = ref(0);
let ticking = false;

const onScroll = () => {
  if (!ticking) {
    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.value) > 0.001) {
        lastProgress.value = progress;

        // 1. 粉色盒子:分段动画
        if (progress < 0.33) {
          anime({
            targets: ".scroll-box",
            translateY: progress * 600,
            scale: 1 + progress * 1.5,
            opacity: 1,
            rotate: 0,
            background: "#f472b6",
            duration: 400,
            easing: "easeOutCubic",
          });
        } else if (progress < 0.66) {
          anime({
            targets: ".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,
            easing: "easeInOutCubic",
          });
        } else {
          anime({
            targets: ".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,
            easing: "easeInCubic",
          });
        }

        // 2. 蓝色盒子:左右来回移动+弹性
        anime({
          targets: ".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,
          easing: "easeOutElastic(1, .5)",
        });

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

        // 4. 文字渐显
        anime({
          targets: ".scroll-text",
          opacity: progress,
          translateY: 100 - progress * 100,
          duration: 400,
          easing: "easeOutCubic",
        });
      }
      ticking = false;
    });
    ticking = true;
  }
};

onMounted(() => {
  window.addEventListener("scroll", onScroll);
});

onUnmounted(() => {
  window.removeEventListener("scroll", onScroll);
});
</script>

<template>
  <div class="h-[2500px] relative">
    <!-- 滚动进度条 -->
    <div class="fixed top-0 left-0 w-full h-2 bg-gray-200 z-50">
      <div
        class="scroll-progress origin-left h-full bg-pink-400 scale-x-0"
      ></div>
    </div>
    <!-- 动画盒子1 -->
    <div
      class="scroll-box w-32 h-32 bg-pink-400 fixed top-20 left-20 rounded-lg shadow-lg"
    ></div>
    <!-- 动画盒子2 -->
    <div
      class="scroll-box2 w-32 h-32 bg-blue-400 fixed top-60 left-60 rounded-lg shadow-lg"
    ></div>
    <!-- 渐显文字 -->
    <div
      class="scroll-text fixed top-[300px] left-1/2 -translate-x-1/2 w-[600px] text-3xl text-gray-700 opacity-0"
    >
      <p>分段动画、弹性、渐变、旋转、缩放、透明度,全部联动!</p>
      <p class="mt-10 text-xl">继续滚动,体验更丰富的滚动动画效果。</p>
    </div>
    <!-- 内容填充 -->
    <div
      class="absolute top-[700px] left-1/2 -translate-x-1/2 w-[600px] text-xl text-gray-700"
    >
      <p>你可以继续添加更多动画元素,或根据滚动区间分段控制动画效果。</p>
    </div>
  </div>
</template>

SVG 动画效果

复制代码
<script setup>
import { ref, onMounted } from "vue";
import anime from "animejs";

const pathRef = ref(null);

onMounted(() => {
  if (pathRef.value) {
    const length = pathRef.value.getTotalLength();
    pathRef.value.style.strokeDasharray = length;
    pathRef.value.style.strokeDashoffset = length;
    anime({
      targets: pathRef.value,
      strokeDashoffset: [length, 0],
      duration: 2000,
      easing: "easeOutCubic",
    });
  }
});
</script>

<template>
  <div class="flex flex-col items-center mt-10">
    <svg width="320" height="120" viewBox="0 0 320 120">
      <path
        ref="pathRef"
        d="M20,60 Q160,10 300,60 T300,110"
        stroke="#f472b6"
        stroke-width="6"
        fill="none"
      />
    </svg>
    <p class="mt-4 text-lg text-gray-700">SVG 路径描边动画</p>
  </div>
</template>

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

相关推荐
拉不动的猪4 分钟前
前端小白之 CSS弹性布局基础使用规范案例讲解
前端·javascript·css
伍哥的传说9 分钟前
React强大且灵活hooks库——ahooks入门实践之开发调试类hook(dev)详解
前端·javascript·react.js·ecmascript·hooks·react-hooks·ahooks
界面开发小八哥39 分钟前
界面控件Kendo UI for Angular 2025 Q2新版亮点 - 增强跨设备的无缝体验
前端·ui·界面控件·kendo ui·angular.js
BTU_YC1 小时前
Neo4j Python 驱动库完整教程(带输入输出示例)
开发语言·python·neo4j
曾几何时`1 小时前
分别使用Cypher与python构建neo4j图谱
开发语言·python·机器学习
midsummer_woo1 小时前
基于springboot+vue+mysql的中药实验管理系统设计与实现(源码+论文+开题报告)
vue.js·spring boot·mysql
屁股割了还要学1 小时前
【C语言进阶】题目练习(2)
c语言·开发语言·c++·学习·算法·青少年编程
Hello.Reader2 小时前
Go-Redis 入门与实践从连接到可观测,一站式掌握 go-redis v9**
开发语言·redis·golang
007php0072 小时前
使用LNMP一键安装包安装PHP、Nginx、Redis、Swoole、OPcache
java·开发语言·redis·python·nginx·php·swoole
枷锁—sha2 小时前
从零掌握XML与DTD实体:原理、XXE漏洞攻防
xml·前端·网络·chrome·web安全·网络安全