three.js总结(第一章)

目录

了解threejs

一、官网

打包工具(PARCEL)

一、官网

二、用Parcel配置环境

1、步骤:

2、配置完成后及展示结果

了解threejs的最基本内容

一、场景(Scene)

Scene()

二、摄像机(Camera)

Camera()

三、Clock(跟踪时间)

四、enableDamping

五、根据尺寸变化自适应画面

gsap动画库

一、官网

二、设置速度


了解threejs

一、官网

一切了解都在官方文档中, 直接看官方文档即可

下面是自己的一些总结, 个人观点(可能有错误或者理解不同)

官方文档:Three.js – JavaScript 3D Library

 github上的代码: GitHub - mrdoob/three.js: JavaScript 3D Library.

 因为是国外网站, 可以在github上面下载安装包, 然后本地打开(有中文, 可操作)

npm install    //安装依赖
npm start      //启动开发者模式

 红色方框内为本地地址

打包工具(PARCEL)

一、官网

选择的优势:

Parcel 是 Web 应用打包工具,适用于经验不同的开发者。它利用多核处理提供了极快的速度,并且不需要任何配置

这也是为什么不选择webpack的原因, 当然webpack肯定可以, 这就需要看个人的爱好以及擅长

官方网站:Parcel - Web 应用打包工具 | Parcel 中文网

二、用Parcel配置环境

1、步骤:

第一步:初始化文件

npm init    //初始化文件 --> 得到package文件

 第二步:安装打包文件

npm install  parcel-bundler  //全局安装parcel

第三步:配置parcel配置(官方文档中有)

{
  "name": "threjs_one",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {              //这里需要配置开发依赖
    "parcel-bundler": "^1.12.5"
  }
}

配置开发依赖

npm install parcel-bundler --save-dev

安装threejs依赖

npm install three --save

--save

简写 -s,将模块安装到项目 node_modules 目录下,也会将模块依赖写入 dependencies 节点,同时运行 npm install 初始化项目时会将模块下载到项目目录下。

--save-dev

简写 -d,将模块安装到项目 node_modules 目录下,也会将模块依赖写入 devDependencies 节点,同时运行 npm install 初始化项目时,会将模块下载到项目目录下。

2、配置完成后及展示结果

了解threejs的最基本内容

具体请看官网


一、场景(Scene)

场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方。

Scene()

创建一个新的场景对象。

二、摄像机(Camera)

摄像机的抽象基类。在构建新摄像机时,应始终继承此类。

Camera()

Camera(角度, 宽高比, 近端, 远端)

创建一个新的Camera(摄像机)。注意:这个类并不是被直接调用的;你所想要的或许是一个 PerspectiveCamera(透视摄像机)或者 OrthographicCamera(正交摄像机)。

这里面的方法都可以在官网中查到, 就是第一个目录: 创建一个场景

物体的位置改变:

cube.position.x = 3;

// 运动就是在每一帧渲染的时候坐标轴的位置变化
  // 黄色小方块每帧在X轴上向前运动0.01,当运动到大于5时回到原点
  cube.position.x += 0.01;
  if(cube.position.x > 5) {
    cube.position.x = 0
  }

物体的大小改变:

cube.scale.set(3, 2, 1)

cube.scale.set(长, 宽, 高) 或者说(x, y, z)

旋转:

cube.rotation.set(Math.PI / 4, 0, 0)

在x轴上旋转PI/4的角度

// 导入整个 three.js核心库
import * as THREE from "three"
import { Clock } from "three";
// 导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
// 导入动画库
import gsap from "gsap";

// console.log(THREE)
// 1.创建场景
const scene = new THREE.Scene();
// 2.创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 2.1设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);

// 3.添加物体
// 3.1创建几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// 3.2设置材质
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });

// 3.3根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 3.4修改几何物体在场景中的位置
// cube.position.x = 3;
cube.scale.set(3, 2, 1)
cube.rotation.set(Math.PI / 4, 0, 0)
// 3.5将几何物体添加到场景中
scene.add(cube)

// 4.初始化渲染器
const renderer = new THREE.WebGLRenderer()
// 4.1设置渲染尺寸的大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 4.2将webgl渲染的canvas内容添加到body中
document.body.appendChild(renderer.domElement);

// 5.使用渲染器, 通过相机将场景渲染出来
// renderer.render(scene, camera)

// 6.控制器(轨道控制器): 查看3d物体
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

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

const clock = new Clock()
// 设置动画
var animate1 = gsap.to(cube.position, {
  x:5, 
  duration: 3, 
  ease: 'power1.inOut', 
  onComplete: () => {
  console.log('动画结束')
  },
  onStart: () => {
  console.log('动画开始')
  },
  repeat: -1,
  yoyo: true
})
window.addEventListener('dblclick', () => {
  if(animate1.isActive()) {
    animate1.pause()
  }else{
    animate1.resume()
  }
})
gsap.to(cube.rotation, {x:2 * Math.PI, duration: 5})
function render() {
  controls.update()
  renderer.render(scene, camera)
  requestAnimationFrame(render);
}

// 原本5是只渲染一次, 当相机通过轨道查看几何物体时,是按帧渲染的
// function render(time) {
//   let t = (time / 1000) % 5;
//   cube.position.x = t * 1;
//   // 运动就是在每一帧渲染的时候坐标轴的位置变化
//   // 黄色小方块每帧在X轴上向前运动0.01,当运动到大于5时回到原点
//   // cube.position.x += 0.01;
//   if(cube.position.x > 5) {
//     cube.position.x = 0
//   }
//   renderer.render(scene, camera);
//   // 渲染下一帧的时候就会调用render函数
//   requestAnimationFrame(render);
// }
// 初始调用一次
render()

// 监听画面变化, 更新渲染画面
window.addEventListener('resize', () => {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 更新渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio)
})

效果图

优化渲染的速度:

// 原本5是只渲染一次, 当相机通过轨道查看几何物体时,是按帧渲染的
function render(time) {
  let t = (time / 1000) % 5;
  cube.position.x = t * 1;
  // 运动就是在每一帧渲染的时候坐标轴的位置变化
  // 黄色小方块每帧在X轴上向前运动0.01,当运动到大于5时回到原点
  // cube.position.x += 0.01;
  if(cube.position.x > 5) {
    cube.position.x = 0
  }
  renderer.render(scene, camera);
  // 渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

原因: 原本的渲染就是根据传进来的time进行进行渲染, 问题在于传进来的time不是匀速(间隔不等), 这样出现掉帧

现在就直接用传进来的时间直接用作x轴的运动长度, 这样的话更加的准确,优化了上述问题

三、Clock(跟踪时间)

创建多个时钟, 跟踪多个物体(解决上述的问题, 只有一个时间函数)

        该对象用于跟踪时间。如果performance.now可用,则 Clock 对象通过该方法实现,否则回落到使用略欠精准的Date.now来实现。

官网看属性: 相当于开发者已经跟你设计好了, 你只需要使用属性就可以得到想要的效果

const clock = new Clock()
function render() {
  // 获取时钟的运行总时长
  let time = clock.getElapsedTime();
  // 获取两次时间的间隔时间
  let deltaTime = clock.getDelta();
  let t = time % 5
  cube.position.x = t * 1
  renderer.render(scene, camera)
  requestAnimationFrame(render);
}

四、enableDamping

这个方法在轨道控制器(OrbitControls)里面

将其设置为true以启用阻尼(惯性),这将给控制器带来重量感。默认值为false。
请注意,如果该值被启用,你将必须在你的动画循环里调用.update()。

controls.enableDamping = true;

controls.update()

五、根据尺寸变化自适应画面

// 监听画面变化, 更新渲染画面
window.addEventListener('resize', () => {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix();
  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 更新渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio)
})

 双击进入/退出全屏

window.addEventListener('dblclick', () => {
  // 声明常量, 页面是不是全屏
  const fullScreenElement = document.fullscreenElement;
  if(!fullScreenElement) {
    // 双击控制进入全屏
    // 让画布对象全屏
    renderer.domElement.requestFullscreen();
  }else{
    // 退出全屏, 使用document对象
    document.exitFullscreen()
  }
})

gsap动画库

一、官网

主要功能就是节省上面的运算时间, 需要你来设置在x, y, z轴上的变化

安装文档: gsap - npm

官方文档: GSAP Docs

 这里主要就是控制对象的属性, 让他按照设置的运动, 节省了自己去算的时间

// 导入动画库
import gsap from "gsap";

const clock = new Clock()
// 设置动画
//设置物体的位置, 调用里面的参数{在x轴上面的终点位置, 持续时间}
gsap.to(cube.position, {x:5, duration: 5})
//参数{在x轴上面的旋转角度, 持续时间}
gsap.to(cube.rotation, {x:2 * Math.PI, duration: 5})
function render() {
  renderer.render(scene, camera)
  requestAnimationFrame(render);
}

二、设置速度

网站:Getting Started with GSAP - Learning Center - GreenSock

 如下方的例子所示:

ease: 后面就可以写对应的参数, 表示速率按照曲线运行

in表示进来的时候速率快

out表示出去的时候速率快

inOut表示进出都速率快

duration表示持续时间

onComplete表示结束的回调函数

onStart表示开始的回调函数

repeat: 5  表示循环5次. 无限循环是-1

yoyo: true 表示往返运动

delay: 2 表示延迟2秒后运动

// 设置动画
gsap.to(cube.position, {
  x:5, 
  duration: 5, 
  ease: 'power1.inOut', 
  onComplete: () => {
  console.log('动画结束')
  },
  onStart: () => {
  console.log('动画开始')
  }
})

监听双击暂停与恢复

原理就是全局监听双击事件,当动画是运动的时候, 就把动画暂停, 不是就恢复

const clock = new Clock()
// 设置动画
var animate1 = gsap.to(cube.position, {
  x:5, 
  duration: 3, 
  ease: 'power1.inOut', 
  onComplete: () => {
  console.log('动画结束')
  },
  onStart: () => {
  console.log('动画开始')
  },
  repeat: -1,
  yoyo: true
})
window.addEventListener('dblclick', () => {
  if(animate1.isActive()) {
    animate1.pause()
  }else{
    animate1.resume()
  }
})

猜你喜欢

转载自blog.csdn.net/weixin_73416102/article/details/128373528