当前位置: 首页 > article >正文

React从基础入门到高级实战:React 核心技术 - 动画与过渡效果:提升 UI 交互体验

React 动画与过渡效果:提升 UI 交互体验

在现代 Web 开发中,动画和过渡效果不仅仅是视觉上的点缀,它们在提升用户体验、引导用户注意力以及增强交互性方面扮演着重要角色。作为一款广受欢迎的前端框架,React 提供了多种实现动画的方式,从简单的 CSS 类名切换到功能强大的动画库如 React Transition Group 和 Framer Motion。本文将深入探讨这些技术,帮助开发者为 React 应用添加流畅、自然且吸引人的动画效果。

本文的目标读者是希望提升 UI 交互体验的开发者,内容包括以下几个方面:

  • CSS 动画与 React:通过类名切换实现简单动画。
  • React Transition Group:使用 CSSTransitionTransitionGroup 实现过渡和列表动画。
  • Framer Motion:声明式动画库,简化复杂动画的实现。
  • 性能优化:避免动画卡顿,确保流畅的用户体验。
  • 实践案例:实现模态框动画和列表过渡效果。
  • 练习任务:完成一个购物车添加动画。
  • 特别推荐:Framer Motion 的简单性和易用性。

通过本文的学习,你将全面掌握 React 中动画和过渡效果的实现方法,并能在实际项目中灵活运用这些技术。


1. CSS 动画与 React:类名切换的基础

1.1 什么是 CSS 动画?

CSS 动画是通过 CSS 样式规则控制 HTML 元素随时间变化的一种技术。它包括两种主要形式:过渡(Transition)关键帧动画(Keyframes)。在 React 中,我们可以通过动态改变元素的类名或样式属性,触发这些动画效果。

  • 过渡(Transition):定义属性从一个值平滑过渡到另一个值的过程,例如透明度从 0 到 1。
  • 关键帧动画(Keyframes):允许定义更复杂的动画序列,通过多个阶段控制元素的样式。

1.2 在 React 中使用 CSS 动画

React 本身并没有内置的动画系统,但它通过状态管理(State)和条件渲染提供了与 CSS 动画结合的天然支持。我们可以通过 useState 或其他状态管理工具控制组件的状态,然后根据状态变化动态切换 CSS 类名,从而触发动画。

1.2.1 基本示例:显示/隐藏动画

让我们从一个简单的显示/隐藏动画开始:

import { useState } from 'react';
import './styles.css';function ToggleAnimation() {const [isVisible, setIsVisible] = useState(false);return (<div><button onClick={() => setIsVisible(!isVisible)}>{isVisible ? '隐藏' : '显示'}</button><div className={`box ${isVisible ? 'visible' : 'hidden'}`}></div></div>);
}export default ToggleAnimation;
/* styles.css */
.box {width: 100px;height: 100px;background-color: #3498db;transition: opacity 0.5s ease-in-out;
}.visible {opacity: 1;
}.hidden {opacity: 0;
}
  • 代码解析
    • isVisible 是一个布尔状态,用于控制元素的显示状态。
    • 根据 isVisible 的值,box 元素的类名会动态切换为 visiblehidden
    • CSS 中的 transition 属性定义了透明度(opacity)变化的动画效果,持续时间为 0.5 秒,使用 ease-in-out 缓动函数。
  • 效果:点击按钮时,方块会平滑地淡入或淡出。
1.2.2 优点与局限性
  • 优点
    • 实现简单,无需额外依赖。
    • 对于基本的淡入淡出、缩放等效果非常高效。
  • 局限性
    • 难以处理复杂的动画序列,例如多个属性同时变化或多个元素协调动画。
    • 不支持动态计算动画的中间状态,灵活性有限。
1.2.3 扩展:使用关键帧动画

如果需要更复杂的动画,可以使用 @keyframes

import { useState } from 'react';
import './styles.css';function BounceAnimation() {const [isBouncing, setIsBouncing] = useState(false);return (<div><button onClick={() => setIsBouncing(!isBouncing)}>{isBouncing ? '停止' : '弹跳'}</button><div className={`ball ${isBouncing ? 'bounce' : ''}`}></div></div>);
}export default BounceAnimation;
/* styles.css */
.ball {width: 50px;height: 50px;background-color: #e74c3c;border-radius: 50%;
}.bounce {animation: bounce 1s infinite;
}@keyframes bounce {0% {transform: translateY(0);}50% {transform: translateY(-100px);}100% {transform: translateY(0);}
}
  • 效果:点击按钮后,圆球会无限上下弹跳。
  • 关键点@keyframes 定义了动画的多个阶段,animation 属性控制其执行。

2. React Transition Group:过渡与列表动画

当 CSS 动画无法满足复杂需求时,React Transition Group 是一个强大的选择。它是一个轻量级库,提供了 CSSTransitionTransitionGroup 两个核心组件,帮助开发者更轻松地实现过渡和列表动画。

2.1 安装与基础设置

首先安装 React Transition Group:

npm install react-transition-group

2.2 CSSTransition:单元素过渡

CSSTransition 组件通过为元素添加特定的类名,控制其进入(enter)和离开(exit)动画。

2.2.1 示例:淡入淡出效果
import { CSSTransition } from 'react-transition-group';
import { useState } from 'react';
import './styles.css';function FadeTransition() {const [isShown, setIsShown] = useState(false);return (<div><button onClick={() => setIsShown(!isShown)}>{isShown ? '隐藏' : '显示'}</button><CSSTransition in={isShown} timeout={500} classNames="fade"><div className="box">淡入淡出元素</div></CSSTransition></div>);
}export default FadeTransition;
/* styles.css */
.box {width: 150px;height: 150px;background-color: #2ecc71;
}.fade-enter {opacity: 0;
}.fade-enter-active {opacity: 1;transition: opacity 500ms ease-in-out;
}.fade-exit {opacity: 1;
}.fade-exit-active {opacity: 0;transition: opacity 500ms ease-in-out;
}
  • 关键属性
    • in:布尔值,控制组件的进入或离开状态。
    • timeout:动画持续时间(毫秒)。
    • classNames:类名前缀,自动生成如 fade-enterfade-exit-active 等类名。
  • 工作原理
    • intrue 时,依次应用 fade-enterfade-enter-active 类名。
    • infalse 时,依次应用 fade-exitfade-exit-active 类名。
2.2.2 注意事项
  • 如果组件被卸载(例如通过条件渲染 {isShown && <div>...</div>}),需要确保 CSSTransition 的父容器始终存在,否则离开动画不会触发。

2.3 TransitionGroup:列表动画

TransitionGroup 组件用于管理一组动态元素(如列表)的进入和离开动画,通常与 CSSTransition 配合使用。

2.3.1 示例:动态列表过渡
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { useState } from 'react';
import './styles.css';function ListTransition() {const [items, setItems] = useState([1, 2, 3]);const addItem = () => setItems([...items, items.length + 1]);const removeItem = (id) => setItems(items.filter((item) => item !== id));return (<div><button onClick={addItem}>添加项目</button><TransitionGroup component="ul" className="list">{items.map((item) => (<CSSTransition key={item} timeout={500} classNames="item"><li>项目 {item}<button onClick={() => removeItem(item)}>删除</button></li></CSSTransition>))}</TransitionGroup></div>);
}export default ListTransition;
/* styles.css */
.list {list-style: none;padding: 0;
}.item-enter {opacity: 0;transform: translateX(-100%);
}.item-enter-active {opacity: 1;transform: translateX(0);transition: all 500ms ease-in-out;
}.item-exit {opacity: 1;transform: translateX(0);
}.item-exit-active {opacity: 0;transform: translateX(100%);transition: all 500ms ease-in-out;
}
  • 效果
    • 添加项目时,新项目从左侧滑入。
    • 删除项目时,项目向右侧滑出。
  • 关键点
    • key 属性确保每个列表项的唯一性,便于动画追踪。
    • TransitionGroup 管理所有子元素的动画状态。
2.3.2 优点与局限性
  • 优点
    • 与 CSS 无缝集成,易于调试。
    • 适合列表和动态内容的动画。
  • 局限性
    • 需要手动编写大量 CSS,复杂动画实现繁琐。
    • 不支持声明式动画定义,灵活性不如现代动画库。

3. Framer Motion:声明式动画的强大工具

Framer Motion 是一个专为 React 设计的动画库,以其声明式 API 和强大的功能而著称。它不仅简化了动画的实现,还支持手势、拖拽和复杂动画序列,是 React 动画的首选工具。

3.1 安装与基础设置

安装 Framer Motion:

npm install framer-motion

3.2 基本用法:Motion 组件

Framer Motion 提供了一系列 motion 组件(如 motion.divmotion.li),通过属性控制动画。

3.2.1 示例:简单缩放动画
import { motion } from 'framer-motion';function ScaleAnimation() {return (<motion.divinitial={{ scale: 0 }}animate={{ scale: 1 }}transition={{ duration: 0.5, ease: 'easeInOut' }}style={{ width: 100, height: 100, backgroundColor: '#9b59b6' }}>缩放元素</motion.div>);
}export default ScaleAnimation;
  • 关键属性
    • initial:初始状态。
    • animate:目标状态。
    • transition:动画配置(如持续时间、缓动函数)。
  • 效果:元素从 0 缩放到 1,过程平滑自然。

3.3 AnimatePresence:管理组件卸载动画

在 React 中,当组件被条件渲染移除时,默认不会有离开动画。Framer Motion 的 AnimatePresence 组件解决了这个问题。

3.3.1 示例:模态框动画
import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';
import './styles.css';function Modal() {const [isOpen, setIsOpen] = useState(false);return (<div><button onClick={() => setIsOpen(true)}>打开模态框</button><AnimatePresence>{isOpen && (<motion.divinitial={{ opacity: 0, y: -50 }}animate={{ opacity: 1, y: 0 }}exit={{ opacity: 0, y: 50 }}transition={{ duration: 0.3 }}className="modal"><h2>模态框标题</h2><p>这是一个简单的模态框。</p><button onClick={() => setIsOpen(false)}>关闭</button></motion.div>)}</AnimatePresence></div>);
}export default Modal;
/* styles.css */
.modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);border-radius: 8px;
}
  • 效果
    • 打开模态框时,从顶部滑入并淡入。
    • 关闭模态框时,向下退出并淡出。
  • 关键点
    • exit 属性定义了离开动画。
    • AnimatePresence 确保组件卸载前执行离开动画。

3.4 列表动画

Framer Motion 也非常适合实现列表动画。

3.4.1 示例:动态列表过渡
import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';
import './styles.css';function AnimatedList() {const [items, setItems] = useState([1, 2, 3]);const addItem = () => setItems([...items, items.length + 1]);const removeItem = (id) => setItems(items.filter((item) => item !== id));return (<div><button onClick={addItem}>添加项目</button><ul className="list"><AnimatePresence>{items.map((item) => (<motion.likey={item}initial={{ opacity: 0, x: -100 }}animate={{ opacity: 1, x: 0 }}exit={{ opacity: 0, x: 100 }}transition={{ duration: 0.5 }}className="list-item">项目 {item}<button onClick={() => removeItem(item)}>删除</button></motion.li>))}</AnimatePresence></ul></div>);
}export default AnimatedList;
/* styles.css */
.list {list-style: none;padding: 0;
}.list-item {padding: 10px;margin: 5px 0;background: #ecf0f1;border-radius: 4px;
}
  • 效果
    • 新项目从左侧滑入。
    • 删除项目时向右侧滑出。
  • 优点
    • 声明式定义动画,代码简洁。
    • 无需手动编写复杂的 CSS 类名。

3.5 高级功能:手势与拖拽

Framer Motion 支持手势和拖拽动画。例如:

import { motion } from 'framer-motion';function DraggableBox() {return (<motion.divdragdragConstraints={{ left: -100, right: 100, top: -100, bottom: 100 }}whileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}style={{ width: 100, height: 100, backgroundColor: '#e67e22' }}/>);
}export default DraggableBox;
  • 效果:方块可拖拽,悬停时放大,点击时缩小。
  • 关键属性
    • drag:启用拖拽。
    • dragConstraints:限制拖拽范围。
    • whileHoverwhileTap:定义交互状态的动画。

4. 性能优化:打造流畅的动画体验

动画的流畅性直接影响用户体验。以下是一些性能优化的关键策略:

4.1 使用 GPU 加速

  • 推荐属性:使用 transform(如 translatescale)和 opacity,这些属性由 GPU 处理,性能更高。
  • 避免重排:避免动画中使用 lefttopwidth 等触发布局重计算的属性。
示例:优化前后的对比
/* 未优化:触发重排 */
.box {transition: left 0.5s;
}
.box-active {left: 100px;
}/* 优化:使用 GPU 加速 */
.box {transition: transform 0.5s;
}
.box-active {transform: translateX(100px);
}

4.2 减少 DOM 操作

  • 批量更新:在动画开始前完成所有 DOM 更新,避免在动画过程中频繁操作 DOM。
  • 虚拟化列表:对于长列表动画,使用 react-windowreact-virtualized 减少渲染开销。

4.3 控制动画频率

  • requestAnimationFrame:在自定义动画中与浏览器刷新率同步。
  • 节流和防抖:在高频事件(如滚动、鼠标移动)中限制动画触发。

4.4 Framer Motion 的性能优势

Framer Motion 内置了性能优化:

  • 支持硬件加速。
  • 自动批量更新动画状态。
  • 提供 layout 属性,优化动态布局动画。
示例:优化布局动画
import { motion } from 'framer-motion';function LayoutAnimation() {return (<motion.divlayoutanimate={{ width: '200px' }}transition={{ duration: 0.5 }}style={{ height: 100, backgroundColor: '#3498db' }}/>);
}
  • layout:自动优化布局变化的动画。

5. 实践案例:模态框动画与列表过渡效果

以下是一个完整的实践案例,展示如何使用 Framer Motion 实现模态框动画和列表过渡效果。

5.1 模态框动画

import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';
import './styles.css';function ModalExample() {const [isOpen, setIsOpen] = useState(false);return (<div><button onClick={() => setIsOpen(true)}>打开模态框</button><AnimatePresence>{isOpen && (<motion.divinitial={{ opacity: 0, scale: 0.8 }}animate={{ opacity: 1, scale: 1 }}exit={{ opacity: 0, scale: 0.8 }}transition={{ duration: 0.4, ease: 'easeInOut' }}className="modal"><h2>欢迎</h2><p>这是一个动画模态框示例。</p><button onClick={() => setIsOpen(false)}>关闭</button></motion.div>)}</AnimatePresence></div>);
}export default ModalExample;
/* styles.css */
.modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;border-radius: 8px;box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
  • 效果:模态框以缩放和淡入的方式打开,关闭时反向执行。

5.2 列表过渡效果

import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';
import './styles.css';function ListExample() {const [items, setItems] = useState(['苹果', '香蕉', '橙子']);const addItem = () => setItems([...items, `水果 ${items.length + 1}`]);const removeItem = (item) => setItems(items.filter((i) => i !== item));return (<div><button onClick={addItem}>添加水果</button><ul className="list"><AnimatePresence>{items.map((item) => (<motion.likey={item}initial={{ opacity: 0, height: 0 }}animate={{ opacity: 1, height: 'auto' }}exit={{ opacity: 0, height: 0 }}transition={{ duration: 0.3 }}className="list-item">{item}<button onClick={() => removeItem(item)}>删除</button></motion.li>))}</AnimatePresence></ul></div>);
}export default ListExample;
/* styles.css */
.list {list-style: none;padding: 0;
}.list-item {padding: 10px;margin: 5px 0;background: #f1c40f;border-radius: 4px;overflow: hidden;
}
  • 效果:列表项以高度和透明度的动画进入和离开。

6. 练习任务:实现购物车添加动画

现在,让我们完成一个练习任务:实现一个购物车添加动画。目标是点击“添加到购物车”按钮时,商品图片从当前位置飞入购物车图标。

6.1 任务要求

  • 使用 Framer Motion 实现动画。
  • 商品图片从当前位置移动到购物车位置,同时缩小并淡出。
  • 动画完成后更新购物车计数。

6.2 实现代码

import { motion, useAnimation } from 'framer-motion';
import { useState } from 'react';
import './styles.css';function ShoppingCartAnimation() {const [cartItems, setCartItems] = useState(0);const controls = useAnimation();const addToCart = async () => {await controls.start({x: 200,y: -100,scale: 0.5,opacity: 0,transition: { duration: 0.6, ease: 'easeInOut' },});setCartItems(cartItems + 1);controls.set({ x: 0, y: 0, scale: 1, opacity: 1 });};return (<div className="cart-container"><motion.divclassName="product"animate={controls}style={{ width: 50, height: 50, backgroundColor: '#e74c3c' }}/><button onClick={addToCart}>添加到购物车</button><div className="cart-icon">购物车: {cartItems}</div></div>);
}export default ShoppingCartAnimation;
/* styles.css */
.cart-container {position: relative;padding: 20px;
}.product {border-radius: 4px;
}.cart-icon {position: absolute;top: 20px;right: 20px;font-weight: bold;
}
  • 效果
    • 点击按钮后,红色方块(模拟商品)飞向右侧上方,缩小并淡出。
    • 动画完成后,方块回到原位,购物车计数加 1。
  • 关键点
    • useAnimation Hook 提供动画控制。
    • controls.start 执行动画,controls.set 重置状态。

6.3 改进建议

  • 真实图片:将方块替换为商品图片。
  • 动态目标:根据购物车图标的实际位置计算动画终点。
  • 多商品支持:为每个商品创建独立的动画实例。

7. 为什么推荐 Framer Motion?

在众多 React 动画解决方案中,Framer Motion 因其简单性和强大功能脱颖而出:

7.1 简单易用

  • 声明式 API:通过属性定义动画,无需复杂的类名管理。
  • 学习曲线平缓:初学者也能快速上手。

7.2 功能强大

  • 支持手势、拖拽、SVG 动画等高级特性。
  • 内置布局动画优化,适合动态 UI。

7.3 性能优秀

  • 自动使用 GPU 加速。
  • 批量更新动画状态,减少性能开销。

7.4 社区支持

  • 官方文档详尽,示例丰富。
  • 社区活跃,问题易于解决。

相比 React Transition Group,Framer Motion 在实现复杂动画时更简洁高效,是现代 React 开发的理想选择。


8. 总结与进阶学习建议

8.1 总结

本文系统介绍了 React 中的动画和过渡效果实现方法:

  • CSS 动画:简单高效,适合基础需求。
  • React Transition Group:灵活控制过渡和列表动画。
  • Framer Motion:声明式、功能强大,推荐用于复杂场景。
  • 性能优化:通过 GPU 加速和减少 DOM 操作提升体验。

8.2 进阶建议

  • 深入 Framer Motion:探索其手势、拖拽和变体(Variants)功能。
  • 尝试其他库:如 React Spring 或 GSAP,了解不同工具的优劣。

希望本文能为你提供全面的指导,让你在 React 项目中自信地实现各种动画效果!


以下是一个完整的 React 动画示例,包含模态框和列表动画:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>React 动画示例</title><script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js"></script><script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script><script src="https://cdn.jsdelivr.net/npm/framer-motion@11.0.0/dist/framer-motion.umd.js"></script><script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.22.9/babel.min.js"></script><style>body {font-family: Arial, sans-serif;padding: 20px;}.modal {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);border-radius: 8px;}.list {list-style: none;padding: 0;}.list-item {padding: 10px;margin: 5px 0;background: #ecf0f1;border-radius: 4"EOT;display: flex;justify-content: space-between;align-items: center;}button {padding: 8px 16px;margin: 5px;background-color: #3498db;color: white;border: none;border-radius: 4px;cursor: pointer;}button:hover {background-color: #2980b9;}</style>
</head>
<body><div id="root"></div><script type="text/babel">const { useState } = React;const { motion, AnimatePresence } = window.FramerMotion;function Modal() {const [isOpen, setIsOpen] = useState(false);return (<div><button onClick={() => setIsOpen(true)}>打开模态框</button><AnimatePresence>{isOpen && (<motion.divinitial={{ opacity: 0, y: -50 }}animate={{ opacity: 1, y: 0 }}exit={{ opacity: 0, y: 50 }}transition={{ duration: 0.3 }}className="modal"><h2>模态框</h2><p>这是一个简单的模态框动画。</p><button onClick={() => setIsOpen(false)}>关闭</button></motion.div>)}</AnimatePresence></div>);}function AnimatedList() {const [items, setItems] = useState([1, 2, 3]);const addItem = () => setItems([...items, items.length + 1]);const removeItem = (id) => setItems(items.filter((item) => item !== id));return (<div><button onClick={addItem}>添加项目</button><ul className="list"><AnimatePresence>{items.map((item) => (<motion.li déput="motion.li"key={item}initial={{ opacity: 0, x: -100 }}animate={{ opacity: 1, x: 0 }}exit={{ opacity: 0, x: 100 }}transition={{ duration: 0.5 }}className="list-item">项目 {item}<button onClick={() => removeItem(item)}>删除</button></motion.li>))}</AnimatePresence></ul></div>);}function App() {return (<div><h1>React 动画示例</h1><Modal /><AnimatedList /></div>);}ReactDOM.render(<App />, document.getElementById('root'));</script>
</body>
</html>

这篇文章和示例代码提供了一个全面的 React 动画指南,从基础到高级技术一应俱全。希望它能帮助你在项目中打造出色的交互体验!

相关文章:

React从基础入门到高级实战:React 核心技术 - 动画与过渡效果:提升 UI 交互体验

React 动画与过渡效果&#xff1a;提升 UI 交互体验 在现代 Web 开发中&#xff0c;动画和过渡效果不仅仅是视觉上的点缀&#xff0c;它们在提升用户体验、引导用户注意力以及增强交互性方面扮演着重要角色。作为一款广受欢迎的前端框架&#xff0c;React 提供了多种实现动画的…...

重读《人件》Peopleware -(13)Ⅱ 办公环境 Ⅵ 电话

当你开始收集有关工作时间质量的数据时&#xff0c;你的注意力自然会集中在主要的干扰源之一——打进来的电话。一天内接15个电话并不罕见。虽然这看似平常&#xff0c;但由于重新沉浸所需的时间&#xff0c;它可能会耗尽你几乎一整天的时间。当一天结束时&#xff0c;你会纳闷…...

Free2AI:企业智能化转型的加速器

随着数字化与智能化的深度交融&#xff0c;企业的竞争舞台已悄然转变为数据处理能力和智能服务水平的竞技场。Free2AI以其三大核心功能——智能数据采集、多格式文档解析、智能FAQ构建&#xff0c;为企业铺设了一条从数据洞察到智能服务的全链路升级之路&#xff0c;成为推动企…...

Python训练营打卡Day40

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 1.彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中 2.展平操作&#xff1a;除第一个维度batchsize外全部展平 3.dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 作…...

制作一款打飞机游戏63:自动保存

1.编辑器的自动保存实现 ‌目标‌&#xff1a;将自动保存功能扩展到所有编辑器&#xff0c;包括脑编辑器、模式编辑器、敌人编辑器和动画/精灵编辑器。‌实现方式‌&#xff1a; ‌代码复制‌&#xff1a;将关卡编辑器中的自动保存代码复制到其他编辑器中。‌标记数据变更‌&a…...

使用animation.css库快速实现CSS3旋转动画效果

CSS3旋转动画效果实现&#xff08;使用Animate.css&#xff09; 下面我将展示如何使用Animate.css库快速实现各种CSS3旋转动画效果&#xff0c;同时提供一个直观的演示界面。 思路分析 引入Animate.css库创建不同旋转动画的展示区域添加控制面板自定义动画效果实现实时预览功…...

基于NetWork的类FNAF游戏DEMO框架

脑洞大开 想做个fnaf1并加入自己的设计.. 开干!!!! #include <stdio.h> #include <iostream> #include <random> #include <ctime>bool leftdoor true, rightdoor true, camddoor true; float power 900,fanusepower 0;typedef struct movement…...

湖北理元理律师事务所:债务优化中的生活保障实践

在债务压力与生活质量失衡的普遍困境中&#xff0c;法律服务的价值不仅在于解决债务问题&#xff0c;更在于帮助债务人重建生活秩序。湖北理元理律师事务所通过其债务优化服务&#xff0c;探索出一条“法律生活”的双轨路径。 债务规划的核心矛盾&#xff1a;还款能力与生存需…...

golang连接sm3认证加密(app)

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5 文档用途 golang连接安全版sm3认证加密数据库,驱动程序详见附件。 详细信息 1.下载Linux golang安装包 go1.17.3.linux-amd64.tar.gz 1.1. 解压安…...

【Zephyr 系列 2】用 Zephyr 玩转 Arduino UNO / MEGA,实现串口通信与 CLI 命令交互

🎯 本篇目标 在 Ubuntu 下将 Zephyr 运行在 Arduino UNO / MEGA 上 打通串口通信,实现通过串口发送命令与反馈 使用 Zephyr Shell 模块,实现 CLI 命令处理 🪧 为什么 Arduino + Zephyr? 虽然 Arduino 开发板通常用于简单的 C/C++ 开发,但 Zephyr 的支持范围远超 STM32…...

AIS常见问题解答(AIS知识补充)

AIS常见问题解答 什么是 AIS&#xff1f; AIS 是“自动识别系统”的缩写。AIS 是一种基于甚高频 (VHF) 的导航和防撞工具&#xff0c;可以实现船舶之间的信息交换。这些信息&#xff08;AIS 数据&#xff09;还会被丹麦海事局运营的岸基 AIS 系统收集。因此&#xff0c;在提及 …...

基于Matlab实现指纹识别系统

【指纹识别系统基础概念】 指纹识别技术是一种生物特征识别技术&#xff0c;它利用人的指纹独一无二的特性进行个人身份的验证。指纹的细节特征&#xff0c;如脊、谷、分岔等&#xff0c;构成了指纹的唯一性&#xff0c;使得指纹识别在安全性、可靠性和便捷性上具有显著优势。…...

Windows10下搭建sftp服务器(附:详细搭建过程、CMD连接测试、连接失败问题分析解决等)

最终连接sftp效果 搭建sftp服务器 1、这里附上作者已找好的 freeSSHd安装包 ,使用它进行搭建sftp服务器。 2、打开freeSSHd安装包,进行安装 (1)、选择完全安装 (2)、安装完成后,对提示窗口选择关闭 (3)、安装完成后,提示是否安装私有密钥。我们选择"是" (4)、安…...

Vue3中Element-Plus中el-input及el-select 边框样式

如果不需要显示下边框&#xff0c;纯无边框直接将 【border-bottom: 1px solid #C0C4CC; 】注掉或去掉即可。 正常引用组件使用即可&#xff0c;无须自定义样式&#xff0c;最终效果CSS样式。 <style scoped> /* 输入框的样式 */ :deep(.el-input__wrapper) { box-sha…...

vue + ant-design + xlsx 实现Excel自定义模板导入功能

Vue Ant Design 扩展&#xff1a;实现Excel自定义模板导入功能 引言 在企业级应用场景中&#xff0c;除了数据导出&#xff0c;模板化导入是另一个核心需求。本文将深入讲解如何基于Vue3 Ant Design Vue xlsx技术栈&#xff0c;实现以下高级导入功能&#xff1a; 自定义模…...

SAP saml2 元数据 HTTP 错误

使⽤事务 SAML2 或 SAML2_IDP 在 ABAP 系统中配置 SAML 2.0 时&#xff0c; Web 页⾯返回 403 已禁⽌、 404 未找到 或 500 服务器内部错误。 在事务 SAML2 中下载元数据时&#xff0c; ⽹页返回 403 已禁⽌、 404 未找到或 500 服务器内部错误。 在事务 SAML2_IDP 中下载…...

知识课堂|sCMOS相机可编程快门模式解析

sCMOS相机凭借高灵敏度、高动态、低读出噪声特性&#xff0c;成为生命科学成像领域的核心设备。在光片荧光显微镜LSFM成像应用中&#xff0c;传统卷帘快门的时序限制可能引发运动伪影或光片照明不均匀问题。可编程快门模式通过精确控制传感器曝光时序&#xff0c;实现与激光扫描…...

数据结构之栈:原理与常用方法

1. 栈的定义 Stack是Vector的一个子类&#xff0c;它实现标准的后进先出堆栈。Stack只定义了创建空堆栈的默认构造方法。&#xff08;实际上是实现了List接口&#xff0c;因为Vector是List的子类&#xff09;。 Stack() // 创建一个空栈 2. 栈的基本操作 // 压栈操作 publi…...

在React框架中使用Braft Editor集成Table表格的详细教程

简介&#xff1a;Braft Editor是一款基于draft-js开发的React富文本编辑器&#xff0c;支持多媒体、自定义样式和扩展功能。其表格扩展模块允许用户插入、调整表格结构&#xff0c;适合需要数据展示的场景&#xff08;如CMS系统、报表工具&#xff09;。 1.安装依赖 yarn add…...

跳动的爱心

跳动的心形图案&#xff0c;通过字符打印和延时效果模拟跳动&#xff0c;心形在两种大小间交替跳动。 通过数学公式生成心形曲线 #include <stdio.h> #include <windows.h> // Windows 系统头文件&#xff08;用于延时和清屏&#xff09; void printHeart(int …...

gbase8s数据库+mybatis问题记录

在实际使用中一般都是mybatis数据库连接池组合使用&#xff0c;单独使用mybatis 连接数据库时&#xff0c;在循环使用PreparedStatement 时 会发生内存泄漏&#xff0c;PreparedStatement资源得不到释放 测试代码片段如下 drawMapper sqlsession.getMapper(DrawMapper.class…...

实现安卓端与苹果端互通的方案多种多样,以下是一些主要的方案

一、使用跨平台开发框架 1.React Native&#xff1a;通过React Native&#xff0c;开发者可以利用React.js的强大生态系统来构建原生移动应用。该框架允许使用相同的代码库在Android和iOS上开发应用&#xff0c;从而节省时间和成本。它支持热重载功能&#xff0c;使得开发者在…...

SpringBoot开发——Spring Boot异常处理全攻略:五大方案实战对比

文章目录 一、血泪教训:异常处理的代价二、五大异常处理方案详解2.1 全局异常处理(推荐方案)2.2 控制器级处理2.3 HTTP状态码注解2.4 ResponseEntity精细控制2.5 自定义异常体系(企业级方案)三、五大方案对比决策表四、四大避坑指南4.1 异常吞噬陷阱4.2 循环依赖问题4.3 异…...

React-props

文章目录 前言✅ 一、什么是 props&#xff1f;✅ 二、props 的特点✅ 三、props 的核心细节 & 常见问题1. **props 是新对象还是引用&#xff1f;**2. **函数作为 props&#xff1a;闭包陷阱**3. **默认值 & 解构默认值**4. **props.children 是什么&#xff1f;**5. …...

【C++篇】list模拟实现

实现接口&#xff1a; list的无参构造、n个val构造、拷贝构造 operator重载 实现迭代器 push_back() push_front() erase() insert() 头尾删 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace liu {//定义list节点temp…...

Oracle exist

Oracle中的EXISTS是用于检查子查询结果是否为空的逻辑运算符&#xff0c;其核心特点和用法如下&#xff1a; ‌基础语法‌ SELECT columns FROM table1 WHERE EXISTS (SELECT 1 FROM table2 WHERE condition); 当子查询返回至少一行时返回TRUE&#xff0c;否则返回FALSE。 ‌执…...

带sdf 的post sim 小结

1.SDF文件主要内容 Delays&#xff08;module&#xff0c;device&#xff0c;interconnect&#xff0c;port&#xff09; Timing checks&#xff08;setup&#xff0c;hold&#xff0c;setuphold&#xff0c;recovery&#xff0c;removal&#xff0c;recrem&#xff09; Timing…...

【面试】喜茶Java面试题目

1、自我介绍、项目介绍&#xff1b; 2、equals 和 的区别&#xff1f;如何重写equals方法&#xff1f; 3、Java中的异常体系&#xff1f;运行时异常和非运行时异常的区别&#xff1f; 4、HashMap的底层数据结构&#xff1f;JDK1.7和1.8的区别&#xff1f; 5、线程池的核心…...

深入浅出:Spring IOCDI

什么是IOC IOC IOC(Inversion of Control)&#xff0c;是一种设计思想&#xff0c;在之前的SpringMVC里就在类上添加RestController和Controller注解就是使用了IOC&#xff0c;这两个注解就是在Spring中创建一个对象&#xff0c;并将注解下的类交给Spring管理&#xff0c;Spr…...

PlankAssembly 笔记 DeepWiki 正交视图三维重建

manycore-research/PlankAssembly | DeepWiki PlankAssembly项目原理 这个项目是一个基于深度学习的3D重建系统&#xff0c;其核心原理是从三个正交视图的工程图纸中重建出3D形状的结构化程序表示。 核心技术原理 1. 问题定义 PlankAssembly旨在从三个正交视图的工程图纸中…...