当前位置:网站首页>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
边栏推荐
- Vertex shader to slice shader procedure, varying variable
- MongoD管理数据库的方法介绍
- 【数字IC验证快速入门】18、SystemVerilog学习之基本语法5(并发线程...内含实践练习)
- postman生成时间戳,未来时间戳
- Cocos creator collision and collision callback do not take effect
- 【数字IC验证快速入门】23、SystemVerilog项目实践之AHB-SRAMC(3)(AHB协议基本要点)
- 使用Scrapy框架爬取网页并保存到Mysql的实现
- Runnable是否可以中断
- Three. JS introductory learning notes 00: coordinate system, camera (temporarily understood)
- [original] all management without assessment is nonsense!
猜你喜欢
Zhongang Mining: Fluorite continues to lead the growth of new energy market
Briefly describe the working principle of kept
【數字IC驗證快速入門】26、SystemVerilog項目實踐之AHB-SRAMC(6)(APB協議基本要點)
#HPDC智能基座人才发展峰会随笔
There is a cow, which gives birth to a heifer at the beginning of each year. Each heifer has a heifer at the beginning of each year since the fourth year. Please program how many cows are there in the
Spin animation of Cocos performance optimization
LeetCode1_ Sum of two numbers
LeetCode2_ Add two numbers
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
Unity's ASE achieves full screen sand blowing effect
随机推荐
How to create Apple Developer personal account P8 certificate
Gd32 F3 pin mapping problem SW interface cannot be burned
[quick start for Digital IC Validation] 26. Ahb - sramc (6) for system verilog project practice (Basic Points of APB Protocol)
[quick start of Digital IC Verification] 26. Ahb-sramc of SystemVerilog project practice (6) (basic points of APB protocol)
Keil5 does not support online simulation of STM32 F0 series
【数字IC验证快速入门】26、SystemVerilog项目实践之AHB-SRAMC(6)(APB协议基本要点)
webgl_ Enter the three-dimensional world (1)
Please supervise the 2022 plan
[quick start of Digital IC Verification] 23. AHB sramc of SystemVerilog project practice (3) (basic points of AHB protocol)
Tkinter after how to refresh data and cancel refreshing
【数字IC验证快速入门】20、SystemVerilog学习之基本语法7(覆盖率驱动...内含实践练习)
The download button and debug button in keil are grayed out
How to understand that binary complement represents negative numbers
有钱人买房就是不一样
Syntaxhighlight highlights the right scroll bar
MongoDB数据库基础知识整理
OpenGL's distinction and understanding of VAO, VBO and EBO
【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
Cocos creator collision and collision callback do not take effect
银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级