【可视化学习】04-Three.js的开发入门与调试配置
发表于:2023-05-14 |

轨道控制器

这个东西就相当于调整我们的眼睛,从不同的位置看物体,这样就可以看到3d的物体了
首先我们要基于上一篇文章中的代码

导入轨道控制器

1
2
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"

创建轨道控制器

1
2
3
4
5
//当前是平面的,让平面立体起来,使用控制器controls
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 添加阻尼,让控制器有惯性,更加真实,必须在动画循环中调用update
controls.enableDamping=true

调用请求动画帧让场景动起来

1
2
3
4
5
6
7
8
9
function render() {
// 阻尼惯性添加
controls.update()
// 使用渲染器通过相机将场景渲染进来
renderer.render(scene, camera);
// 渲染下一帧的时候就会调用render函数
requestAnimationFrame(render)
}
render()

效果图

坐标轴辅助器

常规开发中,我们都是需要坐标轴来更好的帮我们定位位置,接下来添加一个坐标轴辅助器
参数5是坐标轴长度单位

1
2
3
// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper)

效果图

设置物体移动

静态移动

可以通过设置物体mesh的position来修改物体位置,分别可以用set方法设置,或者单个x,y,z设置

1
2
3
// 修改物体的位置
cube.position.set(5,0,0)
// cube.position.x=3

效果图

动态移动

当然我们也可以让物体来回动,只需要在render里面触发代码

1
2
3
4
5
6
7
8
9
10
function render() {
cube.position.x+=0.01;
if(cube.position.x>5){
cube.position.x=0
}
// 使用渲染器通过相机将场景渲染进来
renderer.render(scene, camera);
// 渲染下一帧的时候就会调用render函数
requestAnimationFrame(render)
}

效果图

设置物体缩放

物体缩放和移动的属性是差不多的,移动是position,缩放就是scale

1
2
3
// 修改物体的缩放
cube.scale.set(3,1,2)
// cube.scale.x=3

设置物体旋转

旋转的参数为,4个

  • x,沿x轴旋转角度
  • y,沿y轴旋转角度
  • z,沿z轴旋转角度
  • order,顺序,默认为XYZ,如需更改顺序改写XYZ顺序,必须大写
    1
    2
    // 旋转
    cube.rotation.set(Math.PI / 4,0,0)

应用requestAnimationFrame正确处理动画运动

我们现在这样的运动是不均匀的,每一帧的运动距离是不相同的。我们需要适当修改下代码

1
2
3
4
5
6
7
8
function render(time) {
let t=(time / 1000) % 5;
cube.position.x=t * 2;
// 使用渲染器通过相机将场景渲染进来
renderer.render(scene, camera);
// 渲染下一帧的时候就会调用render函数
requestAnimationFrame(render)
}

通过Clock跟踪时间处理动画

1
2
3
4
5
6
7
8
9
10
11
12
const clock=new THREE.Clock();
function render(time) {
// 获取时钟运行的总时长(单位s)
let time=clock.getElapsedTime();
// // 获取时钟间隔时间(这俩不能一起,一起会导致间隔太短不显示)
// let deltaTime=clock.getDelta();
cube.position.x=time * 2;
// 使用渲染器通过相机将场景渲染进来
renderer.render(scene, camera);
// 渲染下一帧的时候就会调用render函数
requestAnimationFrame(render)
}

通过gsap动画库处理动画

安装导入

1
2
npm i gsap
import gsap from "gsap"

绘制动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 沿着x轴到5,用时5s
gsap.to(cube.position,{x:5,duration:5})
// 沿着x轴旋转一圈,用时5s
gsap.to(cube.rotation,{x:Math.PI*2,duration:5})
// 设置ease设置速率
gsap.to(cube.position,{x:5,duration:5,ease:'power1.inOut'})
// 回调函数
gsap.to(cube.position,{
x:5,
duration:5,
ease:'power1.inOut',
onComplete:()=>{
console.log("动画完成")
},
{
onStart:()=>{
console.log("动画开始")
}
}})

// 重复(repeat是-1则无限次)
gsap.to(cube.rotation,{x:Math.PI*2,duration:5,repeat:2})
// 往返运动yoyo
gsap.to(cube.rotation,{x:Math.PI*2,duration:5,repeat:-1,yoyo:true})
// 延迟delay
gsap.to(cube.rotation,{x:Math.PI*2,duration:5,repeat:-1,yoyo:true,delay:2})

// 点击让动画停止,启动
var animate1=gsap.to(cube.rotation,{x:Math.PI*2,duration:5,repeat:-1,yoyo:true})
window.addEventListener('click',()=>{
if(animate1.isActive()){
animate1.pause();
}
else{
animate1.resume()
}
})

效果图

根据尺寸变化自适应画面

我们调试页面大小分辨率之后可以看到,没用实时更新画布和样式,因此需要添加自适应画面的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
// 监听画面的变化,更新渲染的画面
window.addEventListener("resize", () => {
// console.log("画面变化了")
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器
renderer.setSize(window.innerWidth, window.innerHeight);

// 设置渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio)
})

js控制是否全屏

1
2
3
4
5
6
7
8
9
10
11
window.addEventListener("dblclick", () => {
const fullScreenElement = document.fullscreenElement;
if (!fullScreenElement) {
// 双击控制屏幕进入全屏
renderer.domElement.requestFullscreen()
}
else {
// 退出全屏,使用document对象
document.exitFullscreen()
}
})

应用图形用户界面更改变量

这里使用到了一个库,dat.gui

安装

1
2
3
npm install --save dat.gui
// 导入dat.gui
import * as dat from "dat.gui"

初始化

1
const gui =new dat.GUI()

通过gui调整物体位置

min是最小值,max是最大值,step是每一次调整大小,name是名称,onChange和onFinishChange是事件

1
2
3
4
5
6
const gui =new dat.GUI()
gui.add(cube.position,"x").min(0).max(5).step(0.01).name("移动x轴").onChange((value)=>{
console.log("值被修改了",value)
}).onFinishChange((value)=>{
console.log("完全停下来",value)
})

通过gui调整物体颜色

1
2
3
4
5
6
7
const params={
color:"#ffff00",
}
gui.addColor(params,'color').onChange((value)=>{
console.log("值被修改")
cube.material.color.set(value)
})

通过gui调整是否显示物体

1
gui.add(cube,'visible').name("是否显示")

通过gui触发某个事件

1
2
3
4
5
6
7
8
9
const params={
color:"#ffff00",
fn:()=>{
// 让立方体运动起来
gsap.to(cube.position,{x:5,duration:2,yoyo:true,repeat:-1})
}
}
// 点击触发某个事件
gui.add(params,'fn').name("立方体运动")

通过gui折叠

1
2
const folder=gui.addFolder("设置立方体")
folder.add(cube.material,'wireframe')

效果图

上一篇:
【可视化学习】05-Three.js物体
下一篇:
【可视化学习】03-Three.js的第一个案例