在React中实现好看的动画Framer Motion(案例:跨DOM元素平滑过渡)

news2024/11/24 20:09:03

前言

介绍

Framer Motion 是一个适用于 React 网页开发的动画库,它可以让开发者轻松地在他们的项目中添加复杂和高性能的动画效果。该库提供了一整套针对 React 组件的动画、过渡和手势处理功能,使得通过声明式的 API 来创建动画变得简单直观。

接下来我将带你使用 Framer Motion 实现一个选中样式平滑过渡的案例。

案例

2023-12-16_10-15-30.gif

基本环境

本案例基于 Vite + React + TypeScript + TailwindCSS 搭建。TailwindCSS 不是必须的,我主要是为了不写 CSS 样式,若想实现和本案例相同的效果,可以安装一下 TailwindCSS。

基本页面

基本页面比较简单,主要就是渲染不同的导航链接,当点击时设置选中的导航,在选中的导航内渲染一个 span 用于显示选中样式,App.tsx

import { useState } from "react";

const navs = [
  {
    name: "Home",
    href: "#home",
  },
  {
    name: "About",
    href: "#about",
  },
  {
    name: "Contact",
    href: "#contact",
  },
];

function App() {
  const [activeNav, setActiveNav] = useState("#home");

  return (
    <div className="mx-auto grid h-full max-w-2xl place-items-center space-y-4 py-4">
      <div className="space-y-8">
        <ul className="flex gap-2">
          {navs.map((nav, index) => (
            <li key={index} className="relative">
              <a
                href={nav.href}
                className="block rounded-md px-4 py-2 text-sm font-medium"
                onClick={() => {
                  setActiveNav(nav.href);
                }}
              >
                {nav.name}

                {nav.href === activeNav && (
                  <span className="absolute inset-0 -z-10 rounded-full bg-gray-100"></span>
                )}
              </a>
            </li>
          ))}
        </ul>

        <ul className="flex flex-col gap-2">
          {navs.map((nav, index) => (
            <li key={index} className="relative">
              <a
                href={nav.href}
                className="block rounded-md px-4 py-1 text-sm font-medium hover:bg-gray-100"
                onClick={() => {
                  setActiveNav(nav.href);
                }}
              >
                {nav.name}

                {nav.href === activeNav && (
                  <span className="absolute inset-y-0 left-0 w-1 rounded-full bg-gray-200"></span>
                )}
              </a>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;
  1. navs 数组:定义了导航链接的数据。
  2. activeNav 状态:存储当前选中的导航项。
  3. 导航列表:通过<ul>元素创建垂直和水平的导航条目。
  4. 点击事件处理:更新activeNav状态以高亮显示当前选中导航。
  5. 条件渲染:根据activeNav状态在选中的导航下显示指示标识。

此时已经完成了案例的基本样式,通过点击发现此时还没有任何动画,选中之间的过渡比较生硬。

npm 安装 Framer Motion:

npm install framer-motion

使用 pnpm:

pnpm add framer-motion

修改 app.tsx

import { motion } from "framer-motion";

<motion.span
	className="absolute inset-0 -z-10 rounded-full bg-gray-100"
	layoutId="activeNav"
	transition={{
		type: "spring",
		stiffness: 380,
		damping: 30,
	}}
></motion.span>

<motion.span
	className="absolute inset-y-0 left-0 w-1 rounded-full bg-gray-200"
	layoutId="activeNav2"
	transition={{
		type: "spring",
		stiffness: 380,
		damping: 30,
	}}
></motion.span>

引入 framer-motion,然后把设置选中样式的 span 改为 motion.span,添加 layoutIdtransition 属性,动画设置为 spring 弹簧动画。

layoutId 用来创建动画以平滑地过渡共享元素的布局变化。
transition 属性用来定义动画的持续时间、延迟、缓动函数(如线性、弹性)、循环次数等特性。
stiffness 这个参数影响弹簧的硬度。一个更高的刚度值意味着弹簧更硬,它会更快地回到它的起始位置,导致动画更快地开始并且拥有一个更小的震荡周期。简言之,刚度越大,弹簧越“紧”,动画运动越快。
damping 这个参数影响弹簧动画的阻尼效果,也就是减震效果。一个更高的阻尼值会导致弹簧运动时震荡得更少,从而更快地稳定下来。如果阻尼值设置得很低,动画会在达到静止状态之前在结束位置附近做较多的震荡。

完整代码

import { useState } from "react";

import { motion } from "framer-motion";

const navs = [
  {
    name: "Home",
    href: "#home",
  },
  {
    name: "About",
    href: "#about",
  },
  {
    name: "Contact",
    href: "#contact",
  },
];

function App() {
  const [activeNav, setActiveNav] = useState("#home");

  return (
    <div className="mx-auto grid h-full max-w-2xl place-items-center space-y-4 py-4">
      <div className="space-y-8">
        <ul className="flex gap-2">
          {navs.map((nav, index) => (
            <li key={index} className="relative">
              <a
                href={nav.href}
                className="block rounded-md px-4 py-2 text-sm font-medium"
                onClick={() => {
                  setActiveNav(nav.href);
                }}
              >
                {nav.name}

                {nav.href === activeNav && (
                  <motion.span
                    className="absolute inset-0 -z-10 rounded-full bg-gray-100"
                    layoutId="activeNav"
                    transition={{
                      type: "spring",
                      stiffness: 380,
                      damping: 30,
                    }}
                  ></motion.span>
                )}
              </a>
            </li>
          ))}
        </ul>

        <ul className="flex flex-col gap-2">
          {navs.map((nav, index) => (
            <li key={index} className="relative">
              <a
                href={nav.href}
                className="block rounded-md px-4 py-1 text-sm font-medium hover:bg-gray-100"
                onClick={() => {
                  setActiveNav(nav.href);
                }}
              >
                {nav.name}

                {nav.href === activeNav && (
                  <motion.span
                    className="absolute inset-y-0 left-0 w-1 rounded-full bg-gray-200"
                    layoutId="activeNav2"
                    transition={{
                      type: "spring",
                      stiffness: 380,
                      damping: 30,
                    }}
                  ></motion.span>
                )}
              </a>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1316704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

modbus 通信协议介绍与我的测试经验分享

1、简介 Modbus 协议是一种通信协议&#xff0c;用于工业自动化系统中的设备间通信。该协议最初由 Modicon 公司开发&#xff0c;并于 1979 年发布。 Modbus 协议通过串行通信格式进行通信&#xff0c;在物理层上支持 RS-232、RS-422 和 RS-485 等多种通信方式。在协议层面&am…

YashanDB 携智慧政务方案亮相数字政府建设与数字湾区发展成果博览会

由广东省人民政府主办的第二届数字政府建设峰会暨数字湾区发展成果博览会于 12月8日-10日在广州举办。作为数字政府、智慧城市建设的核心支撑力量&#xff0c;深算院携单机/主备、共享集群、空间数据库等 YashanDB系列产品亮相本次博览会&#xff0c;展示最新的研发成果、场景应…

spring6 基于xml自动装配

目录结构 代码 UserContronller.java package bean.auto.controller;import bean.auto.service.UserService; import bean.auto.service.UserServiceImpl;public class UserContronller {private UserService userService;public void setUserService(UserService userServ…

通过“待办事项列表项目”快速学习Pyqt5的一些特性

Pyqt5相关文章: 快速掌握Pyqt5的三种主窗口 快速掌握Pyqt5的2种弹簧 快速掌握Pyqt5的5种布局 快速弄懂Pyqt5的5种项目视图&#xff08;Item View&#xff09; 快速弄懂Pyqt5的4种项目部件&#xff08;Item Widget&#xff09; 快速掌握Pyqt5的6种按钮 快速掌握Pyqt5的10种容器&…

持续集成交付CICD:Jenkins流水线操作Harbor仓库

目录 一、实验 1.Jenkins主节点安装Docker 2.Jenkins主节点安装Harbor 3.Jenkins从节点安装Docker 4.Jenkins流水线操作Harbor仓库 二、问题 1.Jenkins主节点登录Harbor仓库报错 2.Jenkins流水线里从节点操作docker报错 3.Jenkins流水线里从节点远程登录Harbor仓库报错…

西南科技大学数据库实验二(表数据插入、修改和删除)

一、实验目的 &#xff08;1&#xff09;学会用SQL语句对数据库进行插入、修改和删除数据操作 &#xff08;2&#xff09;掌握insert、update、delete命令实现对表数据插入、修改和删除等更新操作。 二、实验任务 创建数据库&#xff0c;并创建Employees表、Departments表和…

佛山IBM System x3550 M4服务器维修检查

案例背景&#xff1a; 一家位于东莞的制造公司&#xff0c;在其佛山分厂中安装了一台IBM X3550 M4服务器作为其关键业务设备。该服务器负责管理和存储公司的生产数据、ERP系统和供应链数据。在生产过程中&#xff0c;该服务器突然发生了故障&#xff0c;导致佛山分厂的生产中断…

maven+spock

pom配置 话说JunitMockito的组合用起来是真难用&#xff0c;还是Spock的简单&#xff0c;尤其是参数化的测试。junit的Parameter是鸡肋&#xff0c;杂恶心&#xff1b;Theories用来也不爽。 <?xml version"1.0" encoding"UTF-8"?><project xm…

如何预防最新的.locked、.locked1勒索病毒感染您的计算机?

尊敬的读者&#xff1a; 近期&#xff0c;网络安全领域迎来一股新潮——.locked、.locked1勒索病毒的威胁&#xff0c;其先进的加密技术令人生畏。本文将深入剖析.locked、.locked1勒索病毒的阴谋&#xff0c;提供特色数据恢复策略&#xff0c;并揭示锁定恶劣行径的先锋预防手…

如何实现订单自动取消

由于Redis具有过期监听的功能&#xff0c;于是就有人拿它来实现订单超时自动关闭的功能&#xff0c;但是这个方案并不完美。今天来聊聊11种实现订单超时自动关闭的方案&#xff0c;总有一种适合你&#xff01;这些方案并没有绝对的好坏之分&#xff0c;只是适用场景的不大相同。…

linux系统启动时运行web程序

1.修改rc.local文件 执行命令如果找不到会报错command not found &#xff0c;使用全路径即可 找不到的话 可以使用which 命令 找到路径 后台查看执行日志 2.修改rc.local文件的权限 chmod x rc.local 然后reboot 可以查到进程和启动日志

设计模式 简单工厂 工厂方法模式 抽象工厂模式

工厂模式介绍 工厂模式是我们最常用的实例化对象模式了&#xff0c;是用工厂方法代替new操作的一种模式。它是创建型模式。 简单工厂 简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例, 但它不属于GOF 23种设计模式 简单工厂适用于工厂类负责创建的对象较少的场景,…

Docker部署wordpress和Jenkins

准备机器&#xff1a; 192.168.58.151 &#xff08;关闭防火墙和selinux&#xff09; 安装好docker服务 &#xff08;详细参照&#xff1a;http://t.csdnimg.cn/usG0s 中的国内源安装docker&#xff09; 部署wordpress: 创建目录&#xff1a; [rootdocker ~]# mkdi…

2043杨辉三角(C语言)

目录 一&#xff1a;题目 二&#xff1a;思路分析 三&#xff1a;代码 一&#xff1a;题目 二&#xff1a;思路分析 1.通过杨辉三角&#xff0c;不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果&#xff0c;与杨辉三角的形式有所不同&#xff0c;但是我们可以找…

智能优化算法应用:基于秃鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于秃鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于秃鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.秃鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…

【MySQL】SQL通用语法 、介绍SQL分类

SQL通用语法 1.SQL语句可以单行或多行书写&#xff0c;以分号结尾 2.MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写。 3.注释&#xff1a; 单行注释&#xff1a; -- 或 # 多行注释: /* */ SQL分类 SQL分类主要分为4类 分别是 DDL DML DQL DCL

Stable Diffusion 微调及推理优化实践指南

随着 Stable Diffsuion 的迅速走红&#xff0c;引发了 AI 绘图的时代变革。然而对于大部分人来说&#xff0c;训练扩散模型的门槛太高&#xff0c;对 Stable Diffusion 进行全量微调也很难入手。由此&#xff0c;社区催生了一系列针对 Stable Diffusion 的高效微调方案&#xf…

go学习redis的学习与使用

文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1&#xff09;Redis的启动&#xff1a;2&#xff09;Redis的操作的三种方式3&#xff09;说明&#xff1a;Redis安装好后&#xff0c;默认有16个数据库&#xff0c;初始默认使用0…

深入解析 Spring 和 Spring Boot 的区别

目录 引言 1. 设计理念 1.1 Spring 框架的设计理念 1.2 Spring Boot 的设计理念 2. 项目配置 2.1 Spring 框架的项目配置 2.2 Spring Boot 的项目配置 3. 自动配置 3.1 Spring 框架的自动配置 3.2 Spring Boot 的自动配置 4. 微服务支持 4.1 Spring 框架的微服务支持…

C# WPF上位机开发(加密和解密)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在报文传输的过程中&#xff0c;根据报文传输的形态&#xff0c;有两种形式&#xff0c;一种是明文传输&#xff0c;一种是加密传输。当然明文传输…