您是否曾经想过:“我想为您的网站的UI添加一些惊喜...”
简单的按钮还不够,但是太复杂的动画很难处理……这种情况下的完美想法是“爆炸性3D按钮”!
单击时,此按钮将分解成粒子,使其看起来像在爆炸。更重要的是,它具有一种有趣的机制,在一段时间后,它可以恢复其原始形状。
反应和三个。JS使实现这种互动和美丽的UI变得容易。
将来,我们将继续创建课程,并从打字稿x进行三个反应三个光纤!
我们将在YouTube上发布公告,因此请订阅我们的YouTube频道并等待通知!
📺观看YouTube :您可以从此链接
如果您想知道三个纤维可以做什么反应,请参考以下内容!
我们有易于使用的作品!
爆炸3D按钮的演示
单击以查看当您单击它们时爆炸的惊人3D按钮!
您可以在下面的视频中看到成品的演示。
📺在YouTube上观看演示:链接中观看

此外,该项目的源代码可在GitHub上获得。
请下载代码并尝试!
💾github存储库:此链接中检查源代码
如果您想知道,“我已经看过,我该怎么做?”,不用担心!
在本文中,我们将逐步解释如何从头开始创建此3D按钮。
必要的技术和关键库
该项目使用以下技术和库:这是对每个角色的简要说明。
- 反应
- 前端开发图书馆
- 具有基于组件设计的高效UI构造
- 三
- 一个用于在网络上绘制3D图形的库
- 它使处理复杂的WebGL操作变得容易
- 反应三个纤维
- 包装库,用于处理react中的三个js
- 您可以利用React开发风格中的Three.js的强大功能
- 反应你
- 反应三个光纤扩展库
- 反应三个光纤扩展库
总体实施设计
该项目将实现“颗粒聚集以形成按钮,然后单击时,它会爆炸,返回其原始形状”。
- 初始状态(空闲)
-
- 定期排列颗粒以形成按钮的形状。
- 文字“单击我!”将显示在前面。
- 点击事件发生(触发)
-
- 单击按钮将启动所有粒子的爆炸性飞溅动作。
- 此行为称为“爆炸”。
- 爆炸
-
- 颗粒沿随机方向移动。
- 为每个粒子随机设置速度和方向。
- 返回原始形状(重置)
-
- 一定时间后,粒子返回其原始位置并再次形成按钮。
- 背部动作平稳地插值以实现自然动画。
环境准备
本节为您的项目提供初始设置。使用NPX命令创建一个React应用程序,安装所需的库并组织文件夹结构。
创建React应用程序
首先,使用NPX命令创建一个React应用程序。
npx create-react-app爆炸式按钮-Template打字稿
爆炸按钮
是该项目的名称- 网板
通过指定打字稿使用启用打字稿的模板
安装所需的库
安装反应三个光纤和其他库。
CD爆炸按钮NPM安装三个 @react-three/fiber @react-three/drei
- 三:三。
- @react-three/fiber :用于使用react的三个.js的包装纸
- @react-three/drei :有用的帮助者,例如相机控件和文本图纸
查看文件夹结构并删除不必要的文件
从初始状态组织并添加文件夹,如下所示:
基本上,它是默认值,但是对于您不知道的文件,请查看GitHub。
爆炸按钮/├──node_modules/├-公共/├istrc/ src/ src/├istrents/ //目录,用于添加其他组件的目录thing-data /// data// //对于必要时管理数据的文件///页面//页面/ //页面上的组件,page-by-by-page基础上的组件and-by-page基础│- deckodingbuttonpage.tsx //主页代码││││││││└││││││││ ├ - ─tsconfig.json //打字稿设置└ - readme.md // project概述
这次要修改的文件如下:
app.tsx
:应用程序输入点页面/爆炸tuttonpage
:这次要创建的文件夹ExplodingButtonPage.TSX
:主页的组成部分。ExplodingButtonPage.CSS
:特定于页面的样式。
每个步骤的源代码的详细说明
在以下各节中,我们将按顺序详细说明以下五个部分。
- 定义基本设置,例如按钮和粒度,速度和操作时间
- 这些常数在整个项目中使用,可以通过修改它们轻松调整
- 定义组成按钮的每个粒子的数据结构
- 使用打字稿提高代码可读性和可维护性
- 生成构成按钮的立方体粒子和文本粒子
- 在爆炸时随机设置每个粒子的初始位置和速度矢量
- 我们还将实施逻辑以放置“单击我!!!”按钮表面上的字符。
- 在3D空间中绘制生成的颗粒
- 爆炸和返回其原始位置的动画时,
使用Frame
Controls - 使用适当的图纸方法分开文本和立方体。
- 这是控制整体的组成部分
- 执行状态管理(
空闲
和爆炸
- 背景和相机控制设置也将在此处实现。
- 包括
爆炸粒子
以显示粒子
检查整个来源
以下是本文中创建的爆炸性3D按钮的完整源代码。将所有代码放在一起,因此很容易了解其工作原理。
如果您想查看其他来源,请检查Github。
导入'./app.css';从'./pages'import {explodingButtonPage};功能应用程序(){返回(<div className="App"><ExplodingButtonPage /></div> ); }导出默认应用程序;
导入react,{useref,usestate}来自“反应”;从“@react-three/fiber”中导入{canvas,useframe};导入{orbitControls,start,text}来自“@react-three/drei”;从“三”中导入 *为三个; // ====== //第1部分:常数定义// ======== const restry_size = 0.1; // 1个粒度const restry_num_width = 40; //粒子数(水平)const restry_num_height = 20; //粒子数(水平)const restry_num_thickness = 5; //粒子的数量(水平)const buttor_size_width = restric_size * erention_num_width; //按钮尺寸= 1个粒子 *粒子const butt_size_height = restric_size * earth_num_height; //按钮尺寸= 1个粒子 *粒子数量const butt_size_thickness = rentary_size * erention_num_thickness; //按钮大小= 1个粒子 *粒子const text =“单击我!”; // text显示const text_size = button_size_width / text.length; //大小每个字符const text_float_offset = 0.01; //允许文本从按钮表面const const restry_speed = 2.0浮动的距离; //爆炸式const粒子= 5 * 1000的速度; //爆炸的持续时间在秒内const reset_speed = 0.05; //返回原始位置的速度// ========= //第2部分:键入定义// ====键入type present = {id:numbers; //唯一的ID启动位置:trix.vector3; //初始位置:三。vector3; //当前位置:三。vector3; //爆炸速度量表:数字; //大小char?:string; //文本粒子的字符}; // ====== //第3部分:粒子生成函数// ===== const const generateButtonparticles =():粒子[] => {const粒子:粒子[] = []; // ---生成按钮粒子--- for(令x = 0; x <arther_num_width; x ++){for(令y = 0; y <arther_num_height; y ++){for(let z = 0; z = 0; z <arther_num_thickness; z ++ s+z ++) button_size_height / 2,z * ernation_size); preamles.push({id {id:promentles.length,startPosition:position.clone(),位置:position.clone(),速度:new trix trix.vector3((Math.random() - 0.5) * ernation_speed * erention_speed,(Math.random(Math.random() - 0.5) * arth.random() }}} // ---生成文本的粒子---- text.split(“”)。颗粒。push({id:promentles.length,startPosition:position.clone(),位置:position.clone(),速度:new Trix trix vector3((Math.random() - 0.5) * erenth_speed * erention_speed,(atmation_random(Math.random() - 0.5) });返回颗粒; }; // ===== //第4部分:粒子绘图组件// ========== const爆炸粒子:react.fc <{粒子:粒子[];状态:字符串}> =({{粒子,状态})=> {const groupRef = useref<THREE.Group> (无效的); // USEFRAME:处理每个帧(爆炸或返回初始位置)useFrame(((_,delta)=> {groupRef.current?.children..children.foreach((child)=> {const restry.userdata.particle作为粒子; child.position.Add(粒子。 });返回 (<group ref={groupRef}> {extremles.map((粒子)=>粒子.char?(//文本粒子<group key={particle.id} position={particle.position} userData={{ particle }}><Text fontSize={particle.scale} color="white"> {prones.char}</Text></group> ):( //纽扣形粒子<mesh key={particle.id} position={particle.position} userData={{ particle }}><boxGeometry args={[particle.scale, particle.scale, particle.scale]} /><meshStandardMaterial color={"#3498db"} /></mesh> )}}</group> ); }; // ===== //第5部分:主组件// ======= const deckdodingbuttonpage:react.fc =()=> {const [presentes [ematerles] = usestate<Particle[]> (生成Buttonparticles()); const [state,setState] = usestate <“ idle” | “爆炸”>(“ idle”); const handleclick =()=> {if(state ===“ idle”){setState(“ explode”); settimeout(()=> setState(“ idle”),erenth_time); }};返回 ( <div style={{ width: "100vw", height: "100vh", background: "black" }}><Canvas camera={{ position: [0, 0, 8] }}> {/ *背景效果 */} <Stars radius={100} depth={50} count={1000} factor={4} fade /><ambientLight intensity={0.8} /><spotLight position={[10, 10, 10]} intensity={2} castShadow /> {/ *粒子显示 */}<group onClick={handleClick}><ExplodingParticles particles={particles} state={state} /></group> {/ *相机操作 */}<OrbitControls /></Canvas></div> ); };导出默认爆炸ButtonPage;
第1部分:恒定定义
首先,我们将查看每个库的导入和恒定定义。
导入react,{useref,usestate}来自“反应”;从“@react-three/fiber”中导入{canvas,useframe};导入{orbitControls,start,text}来自“@react-three/drei”;从“三”中导入 *为三个; // ====== //第1部分:常数定义// ======== const restry_size = 0.1; // 1个粒度const restry_num_width = 40; //粒子数(水平)const restry_num_height = 20; //粒子数(水平)const restry_num_thickness = 5; //粒子的数量(水平)const button_size_width = rentary_size * erention_num_width; //按钮尺寸= 1个粒子 *粒子const butt_size_height = restric_size * earth_num_height; //按钮尺寸= 1个粒子 *粒子数量const butt_size_thickness = rentary_size * erention_num_thickness; //按钮大小= 1个粒子 *粒子const text =“单击我!”; // text显示const text_size = button_size_width / text.length; //大小每个字符const text_float_offset = 0.01; //允许文本从按钮表面const const restry_speed = 2.0浮动的距离; //爆炸式const粒子= 5 * 1000的速度; //爆炸持续时间(秒)const reset_speed = 0.05; //恢复原始位置的速度
- 尺寸定义
- 要确定按钮的整体尺寸,请通过乘以粒径及其数量来计算它
粒子_size
是一个粒子的立方体的大小- 将粒子数(水平,垂直,深度)分别设置
- 速度和时间的定义
prones_speed
是爆炸时的运动速度粒子时间
是爆炸动画继续的时候
第2部分:类型定义
接下来是类型定义。
JavaScript并不需要,但是这次是用打字稿创建的,因此需要类型定义。
类型粒子= {id:number; //每个粒子起始位置的唯一标识符:trix.vector3; //初始位置:三。vector3; //当前位置速度:三。vector3; //运动速度量表:数字; //大小char?:string; //文本粒子的字符};
- 类型定义的目的
- 清楚地组织粒子所需的数据
Trix.Vector3
是一种表达3D空间中位置和速度的三个类型。char
定义为可选类型(?
第3部分:粒子产生
定义生成按钮和文本粒子的函数。
粒子是一个按钮,它是一个被拆下的谷物。每个字符都是粒子。
它不是将一个按钮分开,而是多个分子聚集在一起形成一个按钮的图像。
这是一个安排每个功能并创建按钮的函数。
const generatebuttonparticles =():粒子[] => {const粒子:粒子[] = []; //生成用于按钮的立方体粒子(令x = 0; x <arther_num_width; x ++){for(令y = 0; y <arthen_num_height; y ++){for(令z = 0; z = 0; z <arther_num_thickness; z ++ s+z ++) button_size_height / 2,z * ernation_size); preamles.push({id {id:promentles.length,startPosition:position.clone(),位置:position.clone(),速度:new trix trix.vector3((Math.random() - 0.5) * ernation_speed * erention_speed,(Math.random(Math.random() - 0.5) * arth.random() }}} //创建文本粒子text.split(“”)。位置。Clone(),速度:新的三。返回颗粒; };
- 生成按钮粒子
- 使用三重循环在纽扣形状(长度,宽度,宽度)中排列颗粒
- 设置每个粒子的
起始位置
)和当前位置(位置
速度
以随机定向设置
- 文本粒子生成
文本
中的每个字符- 每个字符都放在纽扣表面并被视为颗粒
第4部分:粒子图
它定义了一个实际绘制粒子的函数。
const爆炸粒子:react.fc <{粒子:粒子[];状态:字符串}> =({{粒子,状态})=> {const groupRef = useref<THREE.Group> (无效的); useframe((((_,delta)=> {groupRef.current?.children.foreach(((child)=> {const restry.contry.userdata.particle作为粒子; if(state ===“爆炸”) child.position.lerp(reset.startposition,reset_speed);}});返回 (<group ref={groupRef}> {preachles.map(((粒子)=>粒子.char?) <group key={particle.id} position={particle.position} userData={{ particle }}><Text fontSize={particle.scale} color="white"> {prones.char}</Text></group> ):(( <mesh key={particle.id} position={particle.position} userData={{ particle }}><boxGeometry args={[particle.scale, particle.scale, particle.scale]} /><meshStandardMaterial color={"#3498db"} /></mesh> )}}</group> ); };
- 动画控制使用useframe
USEFRAME
是@React-Three/Fiber
,它描述了您想要在3D空间中执行每个帧的处理。Delta
:自上次帧以来的时间。这使得动画运动无关紧要child.position.add()
- 关于爆炸,
delta
速度
(速度向量)并更新粒子位置 clone()
防止原始速度向量被破坏
- 关于爆炸,
LERP
(线性插值)- 逐渐接近原始位置(
起始位置
reset_speed
是速度指示器
- 逐渐接近原始位置(
- 绘制粒子类型(立方体和文字)
- 立方体颗粒(按钮形状部分)
使用标签创建立方体几何(
) 画- 使用
网格标准材料
- 我将数据从
粒子
到UserData
使用框架
更新位置
- 文本粒子
@react-three/
drei
使用组件- 基于粒子尺度(
比例
组
中单独控制,以使每个角色都遵循爆炸
- 立方体颗粒(按钮形状部分)
- 使用组组件的粒子管理
是三个.js中的组组件,允许您一次管理多个对象- 在这种情况下,所有粒子都可以将
它是在内部组织的,并使用GroupRef
- GroupRef.Current.Children
组
中的所有粒子(子元素)- 请参阅每个粒子
userData
第5部分:主要组件
最后,它将是主要组成部分。
它定义了背景和相机(轨道控制)。
const explodingButtonPage:react.fc =()=> {const [粒子] = usestate<Particle[]> (生成Buttonparticles()); const [state,setState] = usestate <“ idle” | “爆炸”>(“ idle”); const handleclick =()=> {if(state ===“ idle”){setState(“ explode”); settimeout(()=> setState(“ idle”),erenth_time); }};返回 ( <div style={{ width: "100vw", height: "100vh", background: "black" }}><Canvas camera={{ position: [0, 0, 8] }}><Stars radius={100} depth={50} count={1000} factor={4} fade /><ambientLight intensity={0.8} /><spotLight position={[10, 10, 10]} intensity={2} castShadow /><group onClick={handleClick}><ExplodingParticles particles={particles} state={state} /></group><OrbitControls /></Canvas></div> ); };
- 状态管理
状态
切换爆炸并重置为初始位置
- 点击事件
- 触发爆炸并在一定时间后将其返回其原始状态。
最后
在本文中,我们将React和3.J组合在一起,以创建一个“爆炸性3D按钮”!通过这个项目,您可能会学到以下几点:
- 如何使用反应三个光纤操作3D空间
- 用粒子实施互动动画
- 国家管理(
USESTATE
)和动画控制(USEFRAME
)
请尝试亲自获得完成的3D按钮!
📺在YouTube上观看演示:链接中观看

此外,该项目的源代码可在GitHub上获得。
请下载代码并尝试!
💾github存储库:此链接中检查源代码
如果您发现这有用,请订阅我们的频道!
将来,我们将继续创建课程,并从打字稿x进行三个反应三个光纤!
我们将在YouTube上发布公告,因此请订阅我们的YouTube频道并等待通知!
📺观看YouTube :您可以从此链接
如果您想知道三个纤维可以做什么反应,请参考以下内容!
我们有易于使用的作品!