环境搭建
- 新建目录: threeJS
- 初始化项目: npm init
- 安装打包构建工具 parcel: npm install parcel-bundler --save-dev
- 安装threejs包: npm install three --save
- 运行项目: 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)
}
引申,动画库 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)
})