ThreeJS入门

77 阅读3分钟

环境搭建

  1. 新建目录: threeJS
  2. 初始化项目: npm init
  3. 安装打包构建工具 parcel: npm install parcel-bundler --save-dev
  4. 安装threejs包: npm install three --save
  5. 运行项目: npm run dev

项目目录:


\---src
    |   index.html
    |
    +---assets
    |   +---css
    |   |       style.css
    |   |
    |   \---imgs
    \---main
            main.js       
\---package.json
\---package-lock.json

package.json

{
  "name": "threejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "three": "^0.146.0"
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.5"
  }
}

执行npm run dev 后,会在项目目录生成dist打包后的文件

创建一个场景

了解threejs基本内容

main.js

//引入threejs包
import * as THREE from "three"

// 目标:了解threejs基本内容
// 添加场景Scene()构建一个新的场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth/window.innerHeight,
    0.1,
    1000
);
// 设置相机位置
camera.position.set(0,0,10);
//在场景中添加相机
scene.add(camera)

// 添加物体
// 创建几何体
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
// 设置材质
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

// 初始化渲染器
const render = new THREE.WebGLRenderer()
render.setSize( window.innerWidth, window.innerHeight );
//将webgl渲染的canvas内容添加到body
document.body.appendChild( render.domElement );

// 使用渲染器,通过相机将场景渲染进去
render.render(scene,camera)

添加轨道控制器,让场景能够动起来

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

// 创建轨道控制器(摄像机360°围绕物体旋转)
const controls = new OrbitControls(camera,renderer.domElement)

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

function render(){
    renderer.render(scene,camera)
    requestAnimationFrame(render)
}
//替换上面的render.render(scene,camera) 
render()

移动物体


// 修改物体的位置以下两种方式都可以
// cube.position.set(5,0,0)
// cube.position.x = 4

通过在render函数中使用改变物体位置的方法,实现物体移动动画

function render(){
    cube.position.x += 0.01
    if(cube.position.x > 5){
        cube.position.x = 0
    }

    renderer.render(scene,camera)
    requestAnimationFrame(render)
}

物体缩放

// 物体缩放
// cube.scale.set(2,2,2) 
//cube.scale.x = 2 

物体旋转

cube.rotation.set(Math.PI/4,0,0)    //x轴旋转45°
cube.rotation.x = Math.PI/4    //功能同上

//实现不断的旋转,在render函数内添加
function render(){
    cube.position.x += 0.01
    if(cube.position.x > 5){
        cube.position.x = 0
    }
    
    cube.rotation.x += 0.01   //也可以直接设置旋转角度

    renderer.render(scene,camera)
    requestAnimationFrame(render)
}

image-20221116162841510.png

引申,动画库 gsap

TweenMax中文网(GreenSock动画平台,GSAP)


// 导入动画库
import gsap from 'gsap'

// 设置物体移动旋转动画
gsap.to(cube.position,{x:5,duration:5})
gsap.to(cube.rotation,{x:2*Math.PI,duration:5})

//控制动画属性方法
gsap.to(cube.position,{
    x:5,
    duration:5,
    ease:"power1.inOut",
    // 设置重复次数,无限次循环 -1
    repeat:-1,
    // 往返运动
    yoyo:true,
    onComplete:()=>{
        console.log("动画完成")
    },
    onStart:()=>{
        console.log("动画开始")
    }
})

// 通过点击控制物体运动暂停
window.addEventListener('click',function(){
    //判断是否是运动状态
    if(animatel.isActive()){
        animatel.pause()	//暂停
    }else{
        animatel.resume()	//继续
    }
   
})

监听窗口变化,改变视口大小

window.addEventListener('resize',()=>{
    // 更新摄像头
    camera.aspect = window.innerWidth/window.innerHeight
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );
})

全屏/退出全屏切换

window.addEventListener('dblclick',()=>{
    const fullScreenElement = document.fullscreenElement;
    if(!fullScreenElement){
        // 双击控制屏幕进入全屏
        renderer.domElement.requestFullscreen()        
    }else{
        // 退出全屏
        document.exitFullscreen();        
    }
})

dat.gui使用

dat.GUI 是一个轻量级的图形用户界面库(GUI 组件),使用这个库可以很容易地创建出能够改变代码变量的界面组件。

一、安装data.gui

npm install --save-dev dat.gui

二、引入包

// 导入dat.gui
import * as dat from "dat.gui"

三、使用


const gui = new dat.GUI();
// 改变物体位置
gui.add(cube.position,"x").min(0).max(5).step(0.5).name("移动x轴").onChange((val)=>{
    console.log("值改变了"+e)
}).onFinishChange((val)=>{
    console.log('完成移动'+val)
})
// 设置物体颜色
const params = {
    color:"#ffff00",
    fn:()=>{
        //物体运动动画
        gsap.to(cube.position,{x:5,duration:5,yoyo:true,repeat:-1})
    }
}
gui.addColor(params,'color').onChange((value)=>{
    console.log('值被改变',value)
    cube.material.color.set(value)
}).name("颜色")
// 控制显示隐藏
gui.add(cube,'visible').name("是否显示");  
// // 添加事件(点击开始执行fn动画)
// gui.add(params,'fn').name('开启动画')

// 添加文件夹
let folder = gui.addFolder('设置立方体')
folder.add(cube.material,'wireframe')
// 添加事件(点击开始执行fn动画),(放到设置立方体文件目录下)
folder.add(params,'fn').name('开启动画').onChange(value=>{
    console.log(value)
})

image-20221117111901900.png