使⽤react-three-fiber加载glb格式3D⽂件,并播放3D模型⾃带动画
⼀、react-three-fiber简介
使⽤可重⽤、⾃包含的组件以声明⽅式构建您的场景,这些组件对状态做出反应、易于交互并且可以利⽤ React 的⽣态系统。 没有任何限制,⼀切⼯作在three.js这⾥将⽆⼀例外地⼯作。 ⽣态完善。
⼆、安装
npm install three @react-three/fiber
三、基础语法
1、创建场景
import{ Canvas }from'@react-three/fiber'
export default function App(){
return(
<div id="canvas-container">
<Canvas />
</div>
)
}
Canvas 组件在幕后做了⼀些重要的设置⼯作:
它设置了⼀个Scene和⼀个Camera,这是渲染所需的基本构建块
它会⾃动处理调整⼤⼩
它每⼀帧都渲染我们的场景
请注意,Canvas 将调整⼤⼩以适合⽗ div,因此您可以通过更改 css 中 #canvas-container 的 width 和 height 来控制它的⼤⼩。
2、添加Mesh组件(属于threejs中物体下的⽹格组件)
表⽰基于以三⾓形为(多边形⽹格)的物体的类。 同时也作为其他类的基类 ,⼀个是three.js 中的⼀个基本对象,它⽤于保存在3D 空间中表⽰对象所需的多边形和材质。我们将使⽤BoxGeometry组件为⼏何体和MeshPhongMaterial组件为材料创建⼀个新⽹格。
为了将这些对象实际添加到我们的场景中,我们将它们安装在Canvas组件中。
import{ Canvas }from'@react-three/fiber'
export default function App(){
return(
<div id="canvas-container">
<Canvas>
<mesh>
<boxGeometry />
<meshPhongMaterial />
</mesh>
</Canvas>
</div>
)
}
上述代码会被编译为如下代码:
const scene =new THREE.Scene()
const camera =new THREE.PerspectiveCamera(75, width / height,0.1,1000)
const renderer =new THREE.WebGLRenderer()
renderer.setSize(width, height)
document.querySelector('#canvas-container').appendChild(renderer.domElement)
const mesh =new THREE.Mesh()
mesh.material =new THREE.MeshPhongMaterial()
scene.add(mesh)
function animate(){
requestAnimationFrame(animate)
}
animate()
当引⼊⼀个mesh组件时,Fiber 会创建⼀个新THREE.Mesh对象,⼏何和材料也是如此。然后,⼏何体和材料被附加到它们的⽗级。
3、构造函数传参
集合体构造函数可以传递三个参数:宽度、长度和深度。
const geometry =new THREE.BoxGeometry(2,2,2)
在fiber中可以使⽤如下⽅式代替上述写法:
<boxGeometry args={[2,2,2]}/>
**请注意,每次更改这些时,都必须重新构造对象! **
4、添加灯光
向场景中添加⼀些灯光
<Canvas>
...
<ambientLight intensity={0.1}/> // 环境光会均匀的照亮场景中的所有物体。
<directionalLight color="red"position={[0,0,5]}/> // 平⾏光是沿着特定⽅向发射的光。这种光的表现像是⽆限远,从它发出的光线都是平⾏的。
</Canvas>
参数传递和上述⼏何传递参数类似。
<directionalLight
// we are setting the position
position={[0,0,5]}
// we are setting the color
color="red"
/>
编译成
const light =new THREE.DirectionalLight()
light.position.set(0,0,5)
四、事件
1、fiber中事件有13个事件
<mesh
onClick={(e) => console.log('click')}
onContextMenu={(e) => console.log('context menu')}
onDoubleClick={(e) => console.log('double click')}
onWheel={(e) => console.log('wheel spins')}
onPointerUp={(e) => console.log('up')}
onPointerDown={(e) => console.log('down')}
onPointerOver={(e) => console.log('over')}
onPointerOut={(e) => console.log('out')}
onPointerEnter={(e) => console.log('enter')}
onPointerLeave={(e) => console.log('leave')}
onPointerMove={(e) => console.log('move')}
onPointerMissed={() => console.log('missed')}
onUpdate={(self) => console.log('props have been updated')}
/>
2、各个事件作⽤
事件名称作⽤
onClick点击⽹格做出响应onContextMenu在纹理上右击⿏标事件
onDoubleClick在纹理上双击事件
onWheel在纹理上滚动⿏标滚轮触发的事件onPointerUp⿏标抬起事件
onPointerDown⿏标按下事件
onPointerOver⿏标滑过
onPointerOut⿏标离开
onPointerEnter事件回调进⼊
onPointerLeave事件回调离开
onPointerMove⿏标移动
onPointerMissed事件消失回调
onUpdate视图更新回调
3、点击放⼤例⼦
<mesh scale={active ? 1.5 : 1} onClick={() => setActive(!active)} ref={myMesh}>
<boxGeometry />
<meshPhongMaterial color="royalblue"/>
</mesh>
五、模型加载
1、引⼊资源
注意: 引⼊资源必须放在public⽂件夹下,否则都会引⼊失败
export default function Model(props){
const group =useRef()
const gltf =useGLTF('/images/xin.gltf');// public下的images
return(
<group ref={group}{...props} dispose={null}>
<primitive object={gltf.scene}/>
</group>
)
}
useGLTF.preload('/images/xin.gltf');// 预加载
2、使⽤资源
import{ Canvas }from"@react-three/fiber";
import{ Suspense }from"react";
import{ Environment }from"@react-three/drei";
import Model from"./Model";
import'./App.css';
import Loader from'./Loader';
export default function App(){
return(
<div className="App">
<Canvas>
<ambientLight intensity={1}/>
<Suspense fallback={<Loader />}>
<Model position={[0,-4,-10]}/>
<Environment preset="apartment" background />// 背景图⽚
</Suspense>
</Canvas>
</div>
);
}
3、资源过⼤过渡动画
import{ Html, useProgress }from'@react-three/drei'
function Loader(){
const{ progress }=useProgress()
return<Html center>{progress}% loaded</Html>
}
六、基本动画
1、 useFrame
useFrame是⼀个 Fiber 挂钩,可让您在 Fiber 渲染循环的每⼀帧上执⾏代码。这可以有很多⽤途,但我们将专注于⽤它构建动画。重要的是要记住Fiber 钩⼦只能在⽗级内部调⽤!
2、使⽤useRef
在每⼀帧直接改变我们的⽹格。⾸先,我们必须reference通过useRef React 钩⼦获取它:
import{ useFrame }from'@react-three/fiber';
export default function Model(props){
const group =useRef();
const gltf =useGLTF("/images/kunchong.glb");
useFrame(({clock})=>{
ation.y = Math.ElapsedTime());
});
return(
<group ref={group}{...props} dispose={null}>
<primitive object={gltf.scene}/>
</group>
);
}
useGLTF.preload("/images/kunchong.glb");
七、react-spring动画,可以实现和css动画⼀样效果
1、安装
npm install three @react-spring/three
2、使⽤
import{ useSpring, animated }from'@react-spring/three'
useSpring - 将值转换为动画值的钩⼦
animated-⽤于你的DOM代替或⽹状的部件,所以不是⽤mesh你sh,如果你希望它受以下因素影响react-spring
import React,{ useRef, useState }from"react";
import{ useGLTF }from"@react-three/drei";
import{ useFrame }from'@react-three/fiber';
import{ useSpring, animated, config }from'@react-spring/three';
export default function Model(props){
animate下载安装const group =useRef();
const gltf =useGLTF("/images/kunchong.glb");
useFrame(({clock})=>{
ation.y = Math.ElapsedTime());
});
const[active, setActive]=useState(false);
const{ scale }=useSpring({ scale: active ?1.5:1, config: config.wobbly });
return(
&up ref={group}{...props} dispose={null} scale={scale} onClick={()=>setActive(!active)}>
<primitive object={gltf.scene}/>
</up>
);
}
useGLTF.preload("/images/kunchong.glb");
您会看到它不仅从⼀个值跳到另⼀个值,⽽是在两个值之间平滑地进⾏动画处理。 我想做的最后⼀步是为动画添加⼀些摇摆不定的效果,为此我们可以config从react-spring以下位置导⼊对象:
import{ useSpring, animated, config }from'react-spring/three';
最后,当我们调⽤钩⼦时,我们可以为 config 传递⼀个值,然后让我们传递wobbly配置:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论