美文网首页
threejs第一节

threejs第一节

作者: Y_Jaaao | 来源:发表于2023-08-31 11:51 被阅读0次
三维坐标系AxesHelper xyz轴
  • three.js坐标轴颜色红R、绿G、蓝B分别对应坐标系的xyz
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();
设置响应式画布与全屏控制
  • 方法1
//监听窗口变化
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
  • 方法2
// 导入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")
小球滚动并控制停止

相关文章

网友评论

      本文标题:threejs第一节

      本文链接:https://www.haomeiwen.com/subject/cppgmdtx.html