当前位置:网站首页>Three. JS introductory learning notes 13: animation learning
Three. JS introductory learning notes 13: animation learning
2022-07-07 15:49:00 【Jiang Duoduo_ Mostly Harmless 】
Reference learning
https://www.ituring.com.cn/book/miniarticle/53322
Playback settings ( Pause 、 Period of time 、 Point in time )
https://blog.csdn.net/u014291990/article/details/103350524
Zoom in and out
https://blog.csdn.net/liu4071325/article/details/52302053
Animation principle
The essence of animation is to use the visual persistence of human eyes , Quickly change the picture , Thus producing the illusion of biological movement .Three.js The animation is realized by redrawing many times per second .
FPS yes (Frames Per Second) It refers to the number of times the picture is redrawn per second .FPS The bigger it is , The smoother the animation effect ,FPS Less than 20 There will be picture stagnation . When FPS achieve 60, If you increase the number of frames, the human eye will not feel the change obviously , Of the movie FPS The standard for the 24,Three.js Animation , commonly FPS stay 30-60
setInterval Method
Customizable fps
setInterval(func, msec)
func Every time msec Function executed in milliseconds , If you will func Defined as a function of redrawing the picture , Can achieve animation effect .setInterval The function returns a id, If you need to stop redrawing , Need to use clearInterval Method , And pass in the id
Need to be in init Call in function
id = setInterval(draw, 20);
// Changes in each frame ( After all , If every frame is the same , Even if redrawn many times , There will still be no animation effect ), Here we let the box in the scene wrap around y Shaft rotation
function draw() {
mesh.rotation.y = (mesh.rotation.y + 0.01) % (Math.PI * 2);
renderer.render(scene, camera);
}
Every time 20 It will be called once in milliseconds draw function , Change the rotation value of the box , And then redraw it . The result is FPS by 50 Rotating box .
We are HTML Add a button to , Press to stop animation :
<button id="stopBtn" onclick="stop()">Stop</button>
function stop() {
if (id !== null) {
clearInterval(id);
id = null;
}
}
Example 1
1. Plug in translation and rotation
2. Click to change color
3. Auto rotate
4. Click the stop button to stop the rotation
Button call draw Function time :
Click the start button , Every click , Change once , Rotation increases 0.01
Button call start Function time :
Animation core code
<body>
<script src="js/three.js"></script>
<script>
<button id="stopBtn" onclick="stop()">stop</button>
<button id="startBtn" onclick="start()">start</button>
function init() {
// init scene
// Omit
// init camera
// Omit
//light
// Omit
// Load two by C4D use blender Turn into fbx Again into json Model files for
// use mesh1 = obj1,mesh2=obj2, You can control the animation of multiple models
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/cfbx3.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(3);//3 Multiple size
mesh1 = obj1;
obj1.position.set(0,1.3,8.5)
obj1.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj1);
});
var loaderC2 = new THREE.ObjectLoader();
loaderC2.load("json/cfbx3.json", function(obj2) {
obj2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj2.scale.multiplyScalar(3);//3 Multiple size
mesh2 = obj2;
obj2.position.set(0,1.3,6)
obj2.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj2);
});
// Animation redrawing Every time 20 One call in milliseconds draw function , I understand that is 20 Redraw once in milliseconds
id = setInterval(draw, 20);
}//init end
// Animation
function draw() {
// Two models rotate
mesh1.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
mesh2.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
renderer.render(scene, camera);
}
// Stop button
function stop() {
if (id !== null) {
clearInterval(id);
id = null;
}
}
// Restart button
function start() {
mesh1.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
mesh2.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
renderer.render(scene, camera);
id = setInterval(draw, 20);
}
</script>
</body>
Complete code
rotationDraw and otherDraw The function executes only once each time the button is pressed , To execute multiple times, you need to call again setInterval(otherDraw, 20), Let it redraw every millisecond 20 Time , So put it in start Function can realize the effect of playing again after pause
<!DOCTYPE html>
<html lang="en">
<head>
<title>3D</title>
<meta charset="utf-8">
<!-- The adaptive -->
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<button class="startBtn" onclick="start1()">start1</button>
<button class="startBtn" onclick="otherDraw()">start2</button>
<script src="js/three.js"></script>
<script type="text/javascript" src="js/OrbitControls.js"></script>
<script>
var stats, light, mesh ,group;
var camera, scene, raycaster, renderer;
var mouse = new THREE.Vector2(), INTERSECTED;// Intersecting
var radius = 100, theta = 0;
init();
function init() {
// init scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
// init camera
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(15,15,15);
// camera.lookAt(new THREE.Vector3(0,0,0));
camera.lookAt( scene.position );
scene.add(camera);
//light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 1, 1, 1 ).normalize();// Vector attribute vector is converted to unit vector , Set the direction to be the same as the original vector , The length is 1
light.intensity=1.5;// Strength
scene.add( light );
// Cache Library
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/cfbx3.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(3);//3 Multiple size
mesh1 = obj1;
obj1.position.set(0,1.3,8.5)
obj1.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj1);
});
var loaderC2 = new THREE.ObjectLoader();
loaderC2.load("json/cfbx3.json", function(obj2) {
obj2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj2.scale.multiplyScalar(3);//3 Multiple size
mesh2 = obj2;
obj2.position.set(0,1.3,6)
obj2.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj2);
});
// ray
raycaster = new THREE.Raycaster();
/* var raycaster = new THREE.Raycaster(); var mouseVector = new THREE.Vector3();*/
//renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementsByTagName("body")[0].appendChild(renderer.domElement);
// monitor
document.addEventListener( "mousedown", onDocumentMouseDown, false );
// Window changes
window.addEventListener( "resize", onWindowResize, false );
// plug-in unit
var controls = new THREE.OrbitControls( camera, renderer.domElement );//camera and render The variable of is consistent with the variable set by the camera and renderer
// If you use animate When the method is used , Delete this function
//controls.addEventListener( 'change', render );
// Make the animation rotate or damp when cycling Does the meaning have inertia
controls.enableDamping = true;
// Dynamic damping coefficient It's the mouse drag rotation sensitivity
//controls.dampingFactor = 0.25;
// Can I zoom
controls.enableZoom = true;
// Whether to rotate automatically
controls.autoRotate = true;
// Set the maximum distance from the camera to the origin
controls.minDistance = 1;
// Set the maximum distance from the camera to the origin
controls.maxDistance = 200;
// Whether to turn on right-click drag and drop
controls.enablePan = true;
// Animation redrawing
id = setInterval(rotationDraw, 20);
}//function end
// Window changes
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
// camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
// Coordinate transformation
function onDocumentMouseDown( event ) {
// Mouse event starts
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// Update the ray with camera and mouse position
raycaster.setFromCamera( mouse, camera );
// Calculate the focus of objects and rays
var intersects = raycaster.intersectObjects( scene.children ,true);// Rays pass through objects , Automatically sort from near to far
// The second kind
if ( intersects.length > 0 ) {
// When there are objects
if ( INTERSECTED != intersects[ 0 ].object ) {
// The last selection is not equal to the current selection , It's time to replace ,intersects[ 0 ] Is the current selection At the front , It is automatically sorted
if ( INTERSECTED )
if( INTERSECTED.material .length==undefined){
INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );// The last selected material should be replaced with the original material
}
INTERSECTED = intersects[ 0 ].object;
if( INTERSECTED.material .length==undefined){
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();// Save the current materials
INTERSECTED.material.emissive.setHex( 0xff0000 );// Color change
}
}
} else {
// When selecting the blank space
//
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
}//mousedown The mouse event ends
// Animation
function rotationDraw() {
mesh1.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
mesh2.rotation.y = (mesh1.rotation.y + 0.01) % (Math.PI * 2);
renderer.render(scene, camera);
}
function otherDraw() {
mesh1.position.y = mesh1.position.y + 1;
mesh2.scale.x = mesh2.scale.x * 2;
mesh2.scale.y = mesh2.scale.y * 2;
mesh2.scale.z = mesh2.scale.z * 2;
// mesh2.scale.multiplyScalar = mesh2.scale.multiplyScalar(2);
renderer.render(scene, camera);
}
function stop() {
if (id !== null) {
clearInterval(id);
id = null;
}
}
function start1() {
id = setInterval(rotationDraw, 20);
}
function start2() {
id = setInterval(otherDraw, 20);
}
</script>
</body>
</html>
requestAnimationFrame Method
This method has no effect , I don't know why
init Function
id = requestAnimationFrame(draw);
Cancel animation
function stop() {
if (id !== null) {
cancelAnimationFrame(id);
id = null;
}
}
and setInterval The difference is , because requestAnimationFrame Only one frame is requested , therefore , In addition to the init Function needs to call , In the function called by it, you need to call again requestAnimationFrame:
function draw() {
mesh.rotation.y = (mesh.rotation.y + 0.01) % (Math.PI * 2);
renderer.render(scene, camera);
id = requestAnimationFrame(draw);
}
To support these browsers , We'd better call before , First judge whether it is defined requestAnimationFrame And the above functions :
var requestAnimationFrame = window.requestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
Load the model and control the animation playback
边栏推荐
- 15. Using the text editing tool VIM
- numpy--数据清洗
- 2022 all open source enterprise card issuing network repair short website and other bugs_ 2022 enterprise level multi merchant card issuing platform source code
- [original] all management without assessment is nonsense!
- jacoco代码覆盖率
- 大表delete删数据导致数据库异常解决
- 2. Heap sort "hard to understand sort"
- 【数字IC验证快速入门】26、SystemVerilog项目实践之AHB-SRAMC(6)(APB协议基本要点)
- MongoD管理数据库的方法介绍
- Runnable是否可以中断
猜你喜欢
2022 all open source enterprise card issuing network repair short website and other bugs_ 2022 enterprise level multi merchant card issuing platform source code
2. Heap sort "hard to understand sort"
Ue4/ue5 multi thread development attachment plug-in download address
The rebound problem of using Scrollview in cocos Creator
How to release NFT in batches in opensea (rinkeby test network)
Starting from 1.5, build a microservice framework link tracking traceid
LeetCode1_ Sum of two numbers
The bank needs to build the middle office capability of the intelligent customer service module to drive the upgrade of the whole scene intelligent customer service
[wechat applet] Chapter (5): basic API interface of wechat applet
【数字IC验证快速入门】20、SystemVerilog学习之基本语法7(覆盖率驱动...内含实践练习)
随机推荐
Getting started with webgl (1)
Using eating in cocos Creator
Pit avoidance: description of null values in in and not in SQL
It's different for rich people to buy a house
Keil5 does not support online simulation of STM32 F0 series
Oracle control file loss recovery archive mode method
Webcodecs parameter settings -avc1.42e01e meaning
[Lanzhou University] information sharing of postgraduate entrance examination and re examination
./ Functions of configure, make and make install
【数字IC验证快速入门】18、SystemVerilog学习之基本语法5(并发线程...内含实践练习)
Whether runnable can be interrupted
[deep learning] semantic segmentation experiment: UNET network /msrc2 dataset
Three. JS introductory learning notes 0: illustration of how webgl and threejs work
一大波开源小抄来袭
nodejs package. JSON version number ^ and~
The bank needs to build the middle office capability of the intelligent customer service module to drive the upgrade of the whole scene intelligent customer service
Points for attention in porting gd32 F4 series programs to gd32 F3 series
jacoco代码覆盖率
Three. JS introductory learning notes 03: perspective projection camera
Shader Language