From three.js rotation animation, I learned about requestAnimationFrame

Time:2024-3-22

catalogs

three.js rotation animation

Pre-animation knowledge

Screen Refresh Rate and Browser Redraw Count

How animation is formed

What are the ways to realize animation

What is a requestAnimationFrame

setTimeout&&setInterval

concluding remarks


three.js rotation animation

Rendering out a cube in three.js is simple, with the following code:
import * as THREE from "three";

// Create the scene
const scene = new THREE.Scene();
// Create a perspective camera
const fov = 45;
const aspect = window.innerWidth / window.innerHeight;
const near = 1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// Positioning camera
camera.position.set(200, 300, 200);
camera.lookAt(0, 0, 0);

// Create a cube (geometry + materials)
const geometry = new THREE.BoxGeometry(10, 10, 10);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
// Add to Scene
scene.add(mesh);

// Create the renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Rendering
renderer.render(scene, camera);
To implement a rotating animation, just modify the code in the rendering section slightly:
//Recursive rendering
function animation() {
  // Change angle
  mesh.rotateY(0.01);
  // Re-render
  renderer.render(scene, camera);
  // Next frame render callback
  requestAnimationFrame(animation);
}
animation();
Effect:

Three.js uses requestAnimationFrame for rendering animations, so why not use setInterval for that? For example, like the following.
// Render functions
function animation() {
  mesh.rotateY(0.01); 
  renderer.render(scene, camera); 
}
// Call the render function periodically at 20ms intervals.
setInterval(animation, 20);
Here’s an exploration of why.

Pre-animation knowledge

We first need to understand some of the concepts and the reasons for the formation of animations.

Screen Refresh Rate and Browser Redraw Count

Screen refresh rate:1sThe number of times the screen is refreshed within the
A typical computer has a screen refresh rate of 60 times per second.1000ms/60≈16.7ms | 60FPS), that is, every16.7msIt will refresh the screen a bit. Of course this value is affected by other factors such as resolution, graphics card, screen size, etc. Since the average computer’s refresh rate is60FPS, so most browsers limit the number of times they redraw, generally not exceeding the number of times the computer redraws, because even if their frequency is exceeded, the user’s experience will not be enhanced.

How animation is formed

Animation is a dynamic illusion formed by continuous playback of static images due to visual residuals caused by the naked eye. Animation is, frankly speaking, a photo, connected to show in sequence, so as to form an animation effect, as long as the frame rate is high, the human eye can not feel the lag, is a continuous video effect. When1sWhen playing 24 pictures in a row in the (24FPS), a smooth animation can be formed, usually the computer refresh frequency is60FPS

What are the ways to realize animation

  • JavaScript: setTimeout and setInterval
  • css3: transition and animation
  • html: canvas and SVG
  • requestAnimationFrame API
Why does HTML5 provide requestAnimationFrame when you can obviously use css3 and setTimeout for animation effects?

What is a requestAnimationFrame

As the name suggests, request(request) Animation(animation) Frame(frame), take a look at the definition of it on MDN.
window.requestAnimationFrame() Tells the browser – you wish to execute an animation and ask the browser to call the specified callback function to update the animation before the next redraw. The method needs to be passed a callback function as an argument that will be executed before the next repaint of the browser.
In layman’s terms, the API call frequency depends on the browser’s refresh rate, that is to say, how many times the browser screen refresh, how many times it executes, generally 60 times per second, it can be understood as an api dedicated to the implementation of animation effects, so that the browser smooth execution of animation effects.
  • So why use this api for animation?
css animation code is simple, performance will be better, because the browser will do some optimization of CSS3 animation ( such as a new layer specifically to run the animation ), the disadvantage is that the animation control is not flexible enough, part of the animation function can not be achieved ( such as scrolling animation ), this time we have to consider the use of js timer to do animation. But there is a big problem with timers doing animations:The animation is jittery., the experience is not effective. Take a look at an example below.
let i = 0;
let requestId: number;
function animation() {
  test.style.marginLeft = `${i}px`;
  requestId = requestAnimationFrame(animation);
  i++;
  if (i > 200) {
    cancelAnimationFrame(requestId);
  }
}
animation();
The above implements an animation with requestAnimationFrame that constantly modifies the left value of the dom element to make it move, which is about 16.7ms per executionAlso requestAnimationFrame returns a request ID, which is a unique value in the list of callback functions. cancelAnimationFrame can be used to cancel the callback function by passing in the request ID. Effect:

The next step is to use the js timer animation again:
let i = 0;
let timerId: number;
function animation() {
  test.style.marginLeft = `${i}px`;
  // Set the execution interval to 0 to mimic requestAnimationFrame.
  timerId = setTimeout(animation, 0);
  i++;
  if (i > 200) {
    clearTimeout(timerId);
  }
}
animation();
Here the setTimeout interval is set to 0 to mimic the requestAnimationFrame. from the code alone, we can’t see any difference, but from the following specific implementation results, we can see the obvious difference. Figure 2 below shows the result of the setTimeout execution:

With the above example, you should know how requestAnimationFrame is better than timer.

setTimeout&&setInterval

The problem with setTimeout and setInterval is that they are not precise enough. This is due to the fact thatevent loop mechanismthat that intrinsic operating mechanism determines thetime interval parameter It actually just specifies that the animation code be added to theevent queuein order to wait for the execution time. If other tasks have been added to the front of the queue, then the animation code has to wait for the front of theUpon completion of the missionThe animation will be executed again, and if the time interval is too short (less than 16.7ms) it will cause frame loss, so it will lead to the animation may not be executed according to the preset, which will degrade the user experience. requestAnimationFrame adoptedBrowser Interval In order to maintain the best drawing efficiency, the interval time is not too short, resulting in excessive drawing and performance consumption; also not because the interval time is too long, the use of animation lag is not smooth, so that a variety of web page animation effects can have astandardizeThe refreshing mechanism, thus saving system resources, increasing system performance and improving visual effects. Now let’s go back to the three.js rotation animation example, where we use the setInterval timer instead of requestAnimationFrame:
import * as THREE from "three";

// Create the scene
const scene = new THREE.Scene();
// Create a perspective camera
const fov = 45;
const aspect = window.innerWidth / window.innerHeight;
const near = 1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// Positioning camera
camera.position.set(200, 300, 200);
camera.lookAt(0, 0, 0);

// Create a cube (geometry + materials)
const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
// Add to Scene
scene.add(mesh);

// Create the renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Render functions
function animation() {
  mesh.rotateY(0.01); 
  renderer.render(scene, camera); 
}
// Call the render function periodically at 20ms intervals, 20ms means the refresh rate is 50FPS (1s/20ms), rendering 50 times per second.
setInterval(animation, 20);
It’s official here that the rendering frequency of calling the render method .render() for rendering can’t be too low.
//Set the period of calling the render function to 200ms, the refresh frequency is equivalent to 5 you can obviously feel the lagging
setInterval("render()",200);
Effect:

You can obviously feel more laggy. So three.js animation rendering generally use requestAnimationFrame, better utilization of browser rendering, to maintain the best drawing efficiency.

Recommended Today

[linux] Permission Understanding

catalogs 1. shell commands and how they work 2. The concept of authority 3. Authority management 2.1 Classification of document visitors (persons) 2.2 File types and access rights (thing attributes) 2.3 Representation of file permission values 2.4 Methods for setting file access rights 3. The file directive 4. Permissions for directories★ 5. Sticky bits★ 6. […]