当前位置:网站首页>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
边栏推荐
- [quick start of Digital IC Verification] 26. Ahb-sramc of SystemVerilog project practice (6) (basic points of APB protocol)
- ./ Functions of configure, make and make install
- Summary of knowledge points of xlua hot update solution
- 【数字IC验证快速入门】25、SystemVerilog项目实践之AHB-SRAMC(5)(AHB 重点回顾,要点提炼)
- 【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
- [target detection] yolov5 Runtong voc2007 data set
- LeetCode3_ Longest substring without duplicate characters
- Implementation of crawling web pages and saving them to MySQL using the scrapy framework
- 【原创】一切不谈考核的管理都是扯淡!
- Starting from 1.5, build a microservice framework link tracking traceid
猜你喜欢

Mesh merging under ue4/ue5 runtime

Vertex shader to slice shader procedure, varying variable

Starting from 1.5, build a microservice framework link tracking traceid

webgl_ Enter the three-dimensional world (2)
Implementation of crawling web pages and saving them to MySQL using the scrapy framework

【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)

Yunxiaoduo software internal test distribution test platform description document

Annexb and avcc are two methods of data segmentation in decoding

AB package details in unity (super detail, features, packaging, loading, manager)

Ue4/ue5 multi thread development attachment plug-in download address
随机推荐
20th anniversary of agile: a failed uprising
Excerpted words
nodejs package. JSON version number ^ and~
JS array foreach source code parsing
Oracle控制文件丢失恢复归档模式方法
Three. JS introductory learning notes 00: coordinate system, camera (temporarily understood)
Vite path alias @ configuration
[quick start of Digital IC Verification] 20. Basic grammar of SystemVerilog learning 7 (coverage driven... Including practical exercises)
Create lib Library in keil and use lib Library
Detailed explanation of Cocos creator 2.4.0 rendering process
Align individual elements to the right under flex layout
[follow Jiangke University STM32] stm32f103c8t6_ PWM controlled DC motor_ code
Cocos uses custom material to display problems
【数字IC验证快速入门】24、SystemVerilog项目实践之AHB-SRAMC(4)(AHB继续深入)
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
Learn good-looking custom scroll bars in 1 minute
从 1.5 开始搭建一个微服务框架链路追踪 traceId
[quick start of Digital IC Verification] 22. Ahb-sramc of SystemVerilog project practice (2) (Introduction to AMBA bus)
numpy--数据清洗
LeetCode3_ Longest substring without duplicate characters