threejs-d-3.0

threejs-d-3.0

一、通过Clock跟踪时间处理动画

我们通过时间属性去控制物体动画,我们需要一个对象用于跟踪时间

const clock = THREE.Clock();
const time = clock.getElapsedTime();//获取时钟运行的总时长
const getDelta = clock.getDelta();//获取两次渲染的间隔时长

Clock( autoStart : Boolean )

autoStart — (可选) 是否要在第一次调用 .getDelta() 时自动开启时钟。默认值是 true

属性

.autoStart : Boolean

如果设置为 true,则在第一次调用 .getDelta() 时开启时钟。默认值是 true

.startTime : Float

存储时钟最后一次调用 start 方法的时间。默认值是 0

.oldTime : Float

存储时钟最后一次调用 start, .getElapsedTime() 或 .getDelta() 方法的时间。默认值是 0

.elapsedTime : Float

保存时钟运行的总时长。默认值是 0

.running : Boolean

判断时钟是否在运行。默认值是 false

方法

.start () : undefined

启动时钟。同时将 startTime 和 oldTime 设置为当前时间。 设置 elapsedTime 为 0,并且设置 running 为 true.

.stop () : undefined

停止时钟。同时将 oldTime 设置为当前时间。

.getElapsedTime () : Float

获取自时钟启动后的秒数,同时将 .oldTime 设置为当前时间。
如果 .autoStart 设置为 true 且时钟并未运行,则该方法同时启动时钟。

.getDelta () : Float

获取自 .oldTime 设置后到当前的秒数。 同时将 .oldTime 设置为当前时间。
如果 .autoStart 设置为 true 且时钟并未运行,则该方法同时启动时钟。

二、Gsap动画库的基本使用

这个动画库的API都有相关的动画示例,所以即使看不懂文档的同学使用也是可以明白的

1.安装并使用

npm install gsap //安装gsap
//main.js
import gsap from 'gsap'
gsap.to(cube.position,{x:20,duration:5})//动画属性,控制物体位置和运动时间(duration)
gsap.to(cube.rotation,{x:Math.PI/4,duration:5})//动画属性,控制物体旋转和运动时间(duration)

当然我们的动画运动肯定不只是匀速运动,也是可以配置我们的缓冲器(和贝赛尔曲线差不多)

gsap.to(cube.position,{x:20,duration:5,ease: "elastic.out(1, 0.2)"})

2.其他属性使用

我们也可以在动画开始、更新、结束去执行回调

我们gsap.to()还有其他动画的属性,比如往返运动、定义关键帧、循环等等

//main.js
import gsap from 'gsap'
gsap.to(cube.position,{
    x:20,
    duration:5,
    ease: "elastic.out(1, 0.2)",
    onStart:()=>{console.log('动画开始')},
    onComplete:()=>{console.log('动画结束')},
    onUpdate:()=>{console.log('更新动画')}
})

我们还可以根据返回对象实现对动画的控制

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>threejs</title>
</head>
<body>
    <div class="nav">
        <button id="play">play()</button>
        <button id="pause">pause()</button>
        <button id="resume">resume()</button>
        <button id="reverse">reverse()</button>
        <button id="restart">restart()</button>
      </div>
    <script src="./main.js"></script>
</body>
</html>
const tween = gsap.to(cube.position,{
    x:20,
    duration:5,
    ease: "elastic.out(1, 0.2)",
    onStart:()=>{console.log('动画开始')},
    onComplete:()=>{console.log('动画结束')},
    onUpdate:()=>{console.log('更新动画')}
})

document.querySelector("#play").onclick = () => tween.play();//开启动画
document.querySelector("#pause").onclick = () => tween.pause();//暂停动画
document.querySelector("#resume").onclick = () => tween.resume();//继续播放动画
document.querySelector("#reverse").onclick = () => tween.reverse();//反转动画
document.querySelector("#restart").onclick = () => tween.restart();//重新开始

三、自适应更改

我们希望我们的画面能够适应我们屏幕的更改

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

四、可视化调节

我们在开发过程中,各种参数比较多,我们需要改一下看一下效果是否符合我们的需要,这样我们的效率就会降低。

所以我们需要一款能快速调节参数的可视化工具dat.gui

1.安装

npm install --save dat.gui

2.使用

修改数值

import dat from 'dat.gui'//引入
const gui = new dat.GUI();//初始化

gui.add(cube.position,'x')//添加要控制的属性
.min(0)//最小值
.max(20)//最大值
.name('移动x坐标')//控制器名称
.step(0.1)//改变刻度
.onChange(value=>console.log('x坐标改变了:'+value))//坐标改变触发
.onFinishChange(value=>console.log('x坐标停止改变了:'+value))//坐标停止改变触发

修改颜色

const parm = {
    color:'#ffffff'
}
gui.addColor(parm,'color')
.name('物体颜色')
.onChange(value=>{
    cube.material.color.set(value)
})

我们的dat.gui还有许多API可以调用,具体的我们可以看dat.gui-api

五、BufferGeometry创建顶点创建矩形

我们所见的立方体,是由顶点坐标创建的面形成的

也可以看webgl里有一些基础的知识可以帮助我们理解点与面的关系

官方描述:是面片、线或点几何体的有效表述。包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销。

//main.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' 


const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const axesHelper = new THREE.AxesHelper( 30 );//轴的线段长度. 默认为 1.
scene.add( axesHelper );//添加到场景

const geometry = new THREE.BufferGeometry();
// 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。
// 因为在两个三角面片里,这两个顶点都需要被用到。
const vertices = new Float32Array( [
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,

     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0, -1.0,  1.0
] );
// itemSize = 3 因为每个顶点都是一个三元组。
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
console.log(cube)

 
scene.add( cube );
const controls = new OrbitControls( camera,renderer.domElement  );
camera.position.set(0,20,100);
controls.update();
function animate() {
   
    requestAnimationFrame( animate );
    controls.update();
    renderer.render( scene, camera );
}
animate();

window.addEventListener('resize',()=>{
    // console.log('屏幕变化了')
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth,window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
})

参考链接:

[GSAP]: “https://github.com/greensock/GSAP
[gsap]: “https://greensock.com/gsap/
[Cubic Bezier]: “https://cubic-bezier.com/#.17,.67,.83,.67
[dat.gui]: “https://www.npmjs.com/package/dat.gui
[dat.gui-api]: “https://github.com/dataarts/dat.gui/blob/master/API.md

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022-2023 alan_mf
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信