最近学习Three.js,此贴供学习记录之用。
学习视频:Three.js教程。讲解很详细,也有配套的笔记,但不包含前端基础知识的讲解,如果是纯小白的朋友,可以找这位up之前的教程学习一下。
文章目录
- .html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>0620</title>
<style>
body{
overflow: hidden;
margin: 0;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports":{
"three": "./three.js/build/three.module.js",
"three/addons/": "./three.js/examples/jsm/"
}
}
</script>
<script src="./0620.js" type="module"></script>
</body>
</html>
gui.js库进行三维场景可视化调整
- 引入dat.gui.js
// 引入dat.gui.js的一个类GUI GUI本质上就是一个前端js库
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
- 创建GUI对象
// 创建GUI对象
const gui = new GUI();
GUI中的方法
.add() 创建交互界面
.addFloder() 创建子菜单
.name() 对交互界面的对象属性命名
.step() 设置交互界面对象属性的调节步长
.onChange() 在对象属性值变化时执行其中函数
.addColor() 为交互界面增加改变颜色选项
.open() 设置交互界面默认为展开状态
.close() 设置交互界面默认为折叠状态
注:若进行调节必须写一渲染循环函数用于更新三维场景,否则调节不予显示
1、.add()
参数:
- 控制对象 对象属性 其他参数
其他参数 包括:
- 1、 两个数字参数,为最大值和最小值 生成滑块
2、一个数组参数 生成下拉列表
3、一个对象参数 生成下拉列表
4、一个布尔参数,做二参,不需其他参数 生成单选框
滑块
// 滑块控制物体x轴的位置
gui.add(mesh.position, 'x', -100, 100);
下拉菜单1
// 数组做参数的下拉菜单控制物体y轴位置
gui.add(mesh.position, 'y', [-100, 0, 100]); //只能移动到数组中给定值的位置
下拉菜单2
// 对象做参数的下拉菜单控制物体z轴位置
gui.add(mesh.position, 'z', {
// left: -100,
// center: 0,
// right: 100,
左: -100,//可以用中文
中: 0,
右: 100
});
单选框
// 设置对象控制bool值
const obj = {
bool: false,
}
gui.add(obj, 'bool').name('是否旋转');
2、.name()
// 滑块控制物体x轴的位置
gui.add(mesh.position, 'x', -100, 100).name('x轴坐标');
3、.step()
// 滑块控制物体x轴的位置 设置调节步长为1
gui.add(mesh.position, 'x', -100, 100).name('x轴坐标');
- 步长调整前后对比
4、.addColor()
// 调整物体颜色
gui.addColor(material, 'color').name('调节颜色');
5、.onChange()
// 调整物体颜色
gui.addColor(material, 'color').name('调节颜色').onChange(function (value) { // 变量value为界面所取颜色
// 以下两种方式表示相同
console.log('material.color: ', material.color);
console.log('material.color: ', value);
})
6、.addFloder()
// .addFolder()创建子菜单以分组
// 创建材质子菜单 子菜单默认展开
const materialFolder = gui.addFolder('材质');
// 调整物体高光亮度
materialFolder.add(material, 'shininess', 0, 50).name('高光亮度');
// 调整物体颜色
materialFolder.addColor(material, 'color').name('调节颜色').onChange(function (value) { // 变量value为界面所取颜色
console.log('material.color: ', material.color);
console.log('material.color: ', value);
});
7、.open()
// 设置子菜单初始为展开状态 默认初始展开
materialFolder.open();
8、.close()
// 设置子菜单初始为折叠状态 默认初始展开
materialFolder.close();
渲染循环
用于更新三维场景的变化
function render () {
if (obj.bool) {
mesh.rotateY(0.01);
}
renderer.render(scene, camera);
requestAnimationFrame(render); // 过固定时间执行render()函数
}
render();
完整.js文件
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 引入dat.gui.js的一个类GUI GUI本质上就是一个前端js库
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
// 创建GUI对象
const gui = new GUI();
/* GUI的.add()方法:创建交互界面 控制对象,对象属性,其他参数
滑块:两个数字参数 最小值,最大值
下拉菜单:一个三个元素数组 三个可选择值
一个对象 三个可选择值
单选框:一个布尔值,做二参,不需要第三个参数
*/
/*
.name()方法,设置中文名
.step()方法,设置步长
.onChange()方法,在gui界面某个值变化时执行此方法
.addColor()方法,添加颜色改变界面
*/
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(100, 100, 100);
scene.add(axesHelper);
const sphere = new THREE.SphereGeometry(25, 3, 2);
const material = new THREE.MeshPhongMaterial({
color: 0x3f49ff,
specular: 0x000fff,
shininess: 30,
})
const mesh = new THREE.Mesh(sphere, material);
mesh.position.set(0, 20, 0);
scene.add(mesh);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 0.8);
pointLight.position.set(400, 400, 400);
scene.add(pointLight);
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 3000);
camera.position.set(100, 100, 100);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
// 调节点光源光强,同时输出到控制台
gui.add(pointLight, 'intensity', 0, 2.0).name('光照强度').step(0.1).onChange(function () {
console.log('pointLight.intensity: ', pointLight.intensity);
});
// 调整物体位置
gui.add(mesh.position, 'x', -100, 100).name('x轴坐标').step(1); // 滑块调整
gui.add(mesh.position, 'y', [-100, 0, 20, 100]).name('y轴坐标'); // 下拉菜单调整
gui.add(mesh.position, 'z', {
// left: -100,
// center: 0,
// right: 100,
左: -100,//可以用中文
中: 0,
右: 100
}).name('z轴坐标'); // 下拉菜单调整
// 设置对象控制bool值
const obj = {
bool: false,
}
gui.add(obj, 'bool').name('是否旋转');
// .addFolder()创建子菜单以分组
// 创建材质子菜单
const materialFolder = gui.addFolder('材质');
materialFolder.close();
// 调整物体高光亮度
materialFolder.add(material, 'shininess', 0, 50).name('高光亮度');
// 调整物体颜色
materialFolder.addColor(material, 'color').name('调节颜色').onChange(function (value) { // 变量value为界面所取颜色
console.log('material.color: ', material.color);
console.log('material.color: ', value);
});
// 渲染循环
function render() {
if (obj.bool) {
mesh.rotateY(0.01);
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
const controls = new OrbitControls(camera, renderer.domElement);
renderer.setClearColor(0x444444, 1);
window.onresize = function () {
render.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
};
// 每延迟固定时间就调用回调函数
setInterval(function (){
console.log('setInterval');
}, 1000);
- 效果图