三维坐标系AxesHelper xyz轴
- three.js坐标轴颜色红R、绿G、蓝B分别对应坐标系的x、y、z轴
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
轨道控制器查看物体OrbitControls
- Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动。拖动鼠标旋转查看各个视角
// 导入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
//添加轨道控制器
const controls = new OrbitControls( camera, renderer.domElement );
//设置带阻尼(慢慢停下,有缓冲)
controls.enableDamping = true;
//设置阻尼系数
controls.dampingFactor = 0.03;
//自动旋转
controls.autoRotate =true;
controls.update();
设置响应式画布与全屏控制
//监听窗口变化
window.addEventListener('resize',()=>{
//重置渲染器宽高比
renderer.setSize(window.innerWidth,window.innerHeight);
//重置相机宽高比
camera.aspect = window.innerWidth/window.innerHeight;
//更新相机投影矩阵
camera.updateProjectionMatrix();
})
//方法一:自定义按钮
//点击按钮显示全屏
var btn = document.createElement('button');
btn.innerHTML = '点击全屏';
btn.style.position = 'absolute';
btn.style.top = '10px';
btn.style.left = '10px';
btn.style.zIndex = '999';
btn.onclick = function(){
//全屏
document.body.requestFullscreen();
console.log('全屏')
}
document.body.appendChild(btn);
//点击按钮退出全屏
var exitBtn = document.createElement('button');
exitBtn.innerHTML = '退出全屏';
exitBtn.style.position = 'absolute';
exitBtn.style.top = '10px';
exitBtn.style.left = '100px';
exitBtn.style.zIndex = '999';
exitBtn.onclick = function(){
//退出全屏
document.exitFullscreen();
console.log('退出全屏')
}
document.body.appendChild(exitBtn);
image.png
// 导入lil.gui
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';
let eventObj = {
Fullscreen:function () {
//全屏
document.body.requestFullscreen();
console.log('全屏')
},
ExitFullscreen:function () {
//退出全屏
document.exitFullscreen();
console.log('退出全屏')
}
}
//创建GUI
const gui = new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");
image.png
运用GUI面板快速调试开发的3D效果
// 导入lil.gui
import {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js';
//创建GUI
const gui = new GUI();
//添加按钮
gui.add(eventObj,"Fullscreen").name("全屏");
gui.add(eventObj,"ExitFullscreen").name("退出全屏");
//控制立方体位置
let folder = gui.addFolder("立方体位置") //相当于一个文件夹
folder.add(cube.position,"x").min(-10).max(10).step(1).name("立方体x轴的位置").onChange((val) =>{
console.log("立方体x轴的位置:"+val) //onChange()每次拖动都输出位置
})
folder.add(cube.position,"y").min(-10).max(10).step(1).name("立方体y轴的位置").onFinishChange((val) =>{
console.log("立方体y轴的位置:"+val) //onFinishChange()直接展示最终位置
})
folder.add(cube.position,"z").min(-10).max(10).step(1).name("立方体z轴的位置").onChange((val) =>{
console.log("立方体z轴的位置:"+val)
})
gui.add(parentCubeMaterial,"wireframe").name("父元素线框模式")
//修改立方体颜色
let colorParams = {
cubeColor :"#00ff00" //默认颜色
}
gui.addColor(colorParams,"cubeColor").name("立方体颜色").onChange((val) =>{
cube.material.color.set(val)
})
GUI面板
为几何体划分顶点组,每个面设置不同材质
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1); //创建立方体
//为每个面设置不同材质
const cubeMaterial0 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cubeMaterial1 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const cubeMaterial2 = new THREE.MeshBasicMaterial({ color: 0x0000ff });
const cubeMaterial3 = new THREE.MeshBasicMaterial({ color: 0xffe200 });
const cubeMaterial4 = new THREE.MeshBasicMaterial({ color: 0x0e4930 });
const cubeMaterial5 = new THREE.MeshBasicMaterial({ color: 0xffffff });
const cubeMaterial6 = new THREE.MeshBasicMaterial({ color: 0x000000 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry,
[cubeMaterial0, cubeMaterial1, cubeMaterial2, cubeMaterial3, cubeMaterial4, cubeMaterial5, cubeMaterial6]
);
// 将几何体添加到场景中
scene.add(cube);
贴图
//加载纹理加载器
let textureLoader = new THREE.TextureLoader()
//加载纹理
let texture = textureLoader.load('./texture/1.jpg')
//加载透明贴图
let alphaMap = textureLoader.load('./texture/2.jpg')
//加载光照贴图
let lightMap = textureLoader.load('./texture/3.jpg')
//创建几何体
let planeGeometry = new THREE.PlaneGeometry(1,1)
//创建材质
let planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff,
map:texture, //添加纹理
transparent:true, //允许透明
alphaMap:alphaMap, //添加透明度贴图
lightMap:lightMap
})
let plane = new THREE.Mesh(planeGeometry, planeMaterial)
scene.add(plane)
贴图
雾Fog
//创建场景雾
//scene.fog = new THREE.Fog(0x999999,0.1,50) //线性雾
scene.fog = new THREE.FogExp2(0x999999,0.1) //指数雾(雾的密度)
//设置背景
scene.background = new THREE.Color(0x999999)
加载gltf模型和加载压缩过的模型
// 导入gltf加载器
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
// 导入draco压缩器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
//实例化加载器gltf
const gltfLoader = new GLTFLoader();
gltfLoader.load(
//模型路径
'../model/san_francisco_city_4k.glb',
(gltf)=>{
// console.log(gltf);
scene.add(gltf.scene);
}
)
//创建 加载Draco压缩
const dracoLoader = new DRACOLoader();
//设置Draco路径
dracoLoader.setDecoderPath('./draco/');
//设置gltf加载器 Draco解码器
gltfLoader.setDRACOLoader(dracoLoader);
光线投射实现3D场景交互事件(点击小球切换颜色)
//创建三个球
const sphere1 = new THREE.Mesh(
new THREE.SphereGeometry(1,32,32),
new THREE.MeshBasicMaterial({
color:0x00ff00
})
)
sphere1.position.x = -4;
scene.add(sphere1)
const sphere2 = new THREE.Mesh(
new THREE.SphereGeometry(1,32,32),
new THREE.MeshBasicMaterial({
color:0x0000ff
})
)
scene.add(sphere2)
const sphere3 = new THREE.Mesh(
new THREE.SphereGeometry(1,32,32),
new THREE.MeshBasicMaterial({
color:0xff00ff
})
)
sphere3.position.x = 4;
scene.add(sphere3)
//创建射线
const raycaster = new THREE.Raycaster()
//创建鼠标向量(鼠标点在画布什么位置上)
const mouse = new THREE.Vector2()
//监听鼠标
window.addEventListener('click', (event) => {
//输出每次鼠标点击的位置
//console.log(event.clientX,event.clientY)
//设置鼠标向量的x,y值
mouse.x = (event.clientX / window.innerWidth )* 2 - 1;
mouse.y = -(event.clientY / window.innerHeight )* 2 + 1;
//console.log(mouse.x,mouse.y)
//通过摄像机和鼠标位置更新射线
raycaster.setFromCamera(mouse,camera)
//计算物体与射线的焦点
const intersects = raycaster.intersectObjects([sphere1,sphere2,sphere3])
console.log(intersects)
if(intersects.length > 0){
if(intersects[0].object._isSelect){
intersects[0].object.material.color.set(
intersects[0].object._originColor
)
intersects[0].object._isSelect = false
return
}
intersects[0].object._isSelect = true
intersects[0].object._originColor = intersects[0].object.material.color.getHex()
intersects[0].object.material.color.set(0xff0000)
}
})
点击小球变红色
补间动画tween(小球滚动)
//导入tween补间动画
import * as TWEEN from 'three/examples/jsm//libs/tween.module.js';
//渲染函数
function animate() {
controls.update();
requestAnimationFrame(animate);
//渲染
renderer.render(scene, camera)
//更新tween
TWEEN.update()
}
animate();
//创建球
const sphere1 = new THREE.Mesh(
new THREE.SphereGeometry(1,32,32),
new THREE.MeshBasicMaterial({
color:0x00ff00
})
)
sphere1.position.x = -4;
scene.add(sphere1)
//移动小球
//创建补间对象
const tween = new TWEEN.Tween(sphere1.position)
tween.to({x:4},2000)
tween.onUpdate(()=>{
//打印小球每次移动的位置
console.log(sphere1.position.x)
}) //2000毫秒
tween.repeat(3) //重复3次
//tween.repeat(Infinity) //重复无数次
tween.yoyo(true)//来回滚动
tween.delay(3000) //延迟3秒后运行
//设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.InOut) //慢慢加速慢慢减速
const tween2 = new TWEEN.Tween(sphere1.position)
tween2.to({y:-4},1000)
//tween1链接tween2,1执行完后,执行2
tween.chain(tween2)
//tween2链接tween1,2执行完后,执行1
tween2.chain(tween)
//启动补间动画
tween.start()
tween.onStart(() =>{
console.log('开始')
})
tween.onComplete(() =>{
console.log('结束')
})
tween.onStop(() =>{
console.log('停止')
})
tween.onUpdate(() =>{
console.log('更新')
})
let params = {
stop:function(){
tween.stop()
}
}
const gui = new GUI()
gui.add(params,"stop")
小球滚动并控制停止
网友评论