首页前端开发HTMLThreejs入门之六:利用HTML5的requestAnimationFrame方法实现物体的旋转

Threejs入门之六:利用HTML5的requestAnimationFrame方法实现物体的旋转

时间2023-07-06 06:18:02发布访客分类HTML浏览1123
导读:认识requestAnimationFramerequestAnimationFrame是html5 提供一个专门用于请求动画的API,用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame...

认识requestAnimationFrame

requestAnimationFrame是html5 提供一个专门用于请求动画的API,用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行 requestAnimationFrame有以下几个特点 1.requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,如果系统绘制率是 60Hz,那么回调函数就会16.7ms再被执行一次,也就是说,requestAnimationFrame的执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。 2.在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,减少了CPU、GPU和内存使用量 3.requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节CPU的开销

Threejs中利用requestAnimationFrame实现动画

接上节内容,首先在index.js中定义一个函数,在函数中调用requestAnimationFrame()方法,实现周期性循环执行

function render() {

  // requestAnimationFrame 实现周期性循环执行 
  requestAnimationFrame(render)//请求再次执行渲染函数render,渲染下一帧
}

在render函数中,我们调用mesh的旋转函数,给它一个旋转弧度,使其沿y周旋转

// 定义一个render函数
function render() {

  // requestAnimationFrame 实现周期性循环执行 
  mesh.rotateY(0.01) //y轴旋转的弧度
  requestAnimationFrame(render)//请求再次执行渲染函数render,渲染下一帧
}

然后在js中调用render函数,刷新浏览器发现物体仍然是静止的状态,这里要注意,我们在render周期函数中每次都让mesh旋转0.01孤度,其实是已经执行了的,但是我们的渲染器没有更新,所以不会显示 我们应该将渲染器的渲染函数也放到render中

// 定义一个render函数
function render() {

  // requestAnimationFrame  
  mesh.rotateY(0.01)//沿y轴旋转的弧度,单位 弧度
  renderer.render(scene,camera)
  requestAnimationFrame(render)//请求再次执行渲染函数render,渲染下一帧
}

render()

刷新浏览器,发现物体已经沿y轴自动旋转了。

代码优化

1、上面定义了一个render函数用于定时刷新渲染器,因此,我们之前的相机控件轨道控制器OrbitControls的监听change事件就可以取消掉了,因为render函数是周期执行的,总会渲染页面 2、我们之前的renderer.render(scene,camera)这句代码也可以取消了,统一在render函数中渲染。

完整代码如下

import * as THREE from 'three'
// 引入轨道控制器扩展库OrbitControls.js
import {
 OrbitControls }
 from 'three/addons/controls/OrbitControls.js'

// 创建一个三维场景,相当于一个画布
const scene = new THREE.Scene()

// 创建一个几何体,相当于在画布上想要呈现的物体
const geometry = new THREE.BoxGeometry(100,100,100)

// 创建材质,相当于画画时的颜料
// const material = new THREE.MeshBasicMaterial({

//   color:0xff0000,//设置颜色
//   transparent:true,//开启透明
//   opacity:0.5//设置透明度
// }
)
const material = new THREE.MeshLambertMaterial({

  color:0xff0000,//设置颜色 
}
    )
// 添加辅助坐标轴
// const axesHelper = new THREE.AxesHelper(100)
// scene.add(axesHelper)

// 创建物体,相当于在画物体的过程,将上面的几何体和材质结合起来形成物体
const mesh = new THREE.Mesh(geometry,material)
// 设置物体在场景中的位置
mesh.position.set(0,10,0)
// 将物体添加到场景中,相当于将物体添加到画布汇总
scene.add(mesh)
// console.log(mesh);
    
// 创建环境光
const light = new THREE.AmbientLight(0x404040,1)
scene.add(light)
// 创建点光 参数1 光的颜色,参数2 光的强度
const pointLight = new THREE.PointLight(0xffffff,1)
// 点光源的位置 
pointLight.position.set(100,100,100)
scene.add(pointLight)

// 创建点光源辅助对象
const pointLightHelper = new THREE.PointLightHelper(pointLight,10)
scene.add(pointLightHelper)
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff,1)
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算光线的方向
directionalLight.position.set(80,100,50)
// 光的方向指向对象网格模型mesh,不设置默认为0,0,0
directionalLight.target = mesh
scene.add(directionalLight)
// 创建平行光辅助对象
const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight,10,0x00ff00)
scene.add(directionalLightHelper)
// 聚光灯
const spotLight = new THREE.SpotLight( 0xffffff );
    
spotLight.position.set( 0, 200, 100 );

scene.add(spotLight)
// 创建聚光灯辅助对象
const spotLightHelper = new THREE.SpotLightHelper(spotLight,0x0000ff)
scene.add(spotLightHelper)

// 创建一个相机,相机相当于画家的眼睛,
// PerspectiveCamera 透视相机:有四个参数,fov:视角,aspect:宽高比,一般定位为相机照射物体的宽高比值,
// near:近端点,离相机最近的点,far:远端点,离相机最远的点
const width = 600
const height = 400
const camera = new THREE.PerspectiveCamera(70,width/height,1,800)
// 设置相机的位置,即画家的眼睛离画布的位置
camera.position.set(200,200,200)
// 设置相机要看的位置,即眼睛要看的物体的位置
// 相机看原点
// camera.lookAt(0,0,0)
// 相机看向物体
camera.lookAt(mesh.position) 

// 创建webgl渲染器
const renderer = new THREE.WebGLRenderer()
// canvas画布宽高
renderer.setSize(width,height)
// 执行渲染操作,将scene和camera关联起来,
// 相当于太阳,你有一个空间scene,空间中有物体,有人的眼睛camera,但是没有光是看不到物体的
// renderer.render(scene,camera)
// 把渲染结果canvas画布,添加到网页上
// document.body.appendChild(renderer.domElement)
document.getElementById('webgl').appendChild(renderer.domElement)
// 定义一个render函数
function render() {

  // requestAnimationFrame  
  mesh.rotateY(0.01)//沿y轴旋转的弧度,单位 弧度
  renderer.render(scene,camera)
  requestAnimationFrame(render)//请求再次执行渲染函数render,渲染下一帧
}

render()
// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera,renderer.domElement)
// 监听轨道控制器的change事件,监听到改变时,重新执行渲染操作渲染三维场景
// controls.addEventListener('change',function(){
 
//   renderer.render(scene,camera)
// }
    )

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

渲染html5函数浏览器入门

若转载请注明出处: Threejs入门之六:利用HTML5的requestAnimationFrame方法实现物体的旋转
本文地址: https://pptw.com/jishu/291390.html
SAP UI5 中的数字 5 代表什么含义? 在2022年使用Python调用Windows 11的通知系统

游客 回复需填写必要信息