当前位置:网站首页>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
边栏推荐
- The "go to definition" in VS2010 does not respond or prompts the solution of "symbol not found"
- What are the safest securities trading apps
- 银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级
- Whether runnable can be interrupted
- JS array foreach source code parsing
- 2022全开源企业发卡网修复短网址等BUG_2022企业级多商户发卡平台源码
- 使用cpolar建立一个商业网站(2)
- Spin animation of Cocos performance optimization
- Oracle控制文件丢失恢复归档模式方法
- Three. JS introductory learning notes 03: perspective projection camera
猜你喜欢

Ida Pro reverse tool finds the IP and port of the socket server

【数字IC验证快速入门】22、SystemVerilog项目实践之AHB-SRAMC(2)(AMBA总线介绍)

How to release NFT in batches in opensea (rinkeby test network)

Ue4/ue5 multi thread development attachment plug-in download address

Streaming end, server end, player end

Typescript release 4.8 beta

Cocos uses custom material to display problems

Tkinter after how to refresh data and cancel refreshing

The download button and debug button in keil are grayed out

居然从408改考自命题!211华北电力大学(北京)
随机推荐
How to deploy the super signature distribution platform system?
Asynchronous application of generator function
[quick start of Digital IC Verification] 18. Basic grammar of SystemVerilog learning 5 (concurrent threads... Including practical exercises)
Pit avoidance: description of null values in in and not in SQL
Cocos makes Scrollview to realize the effect of zooming in the middle and zooming out on both sides
Cut ffmpeg as needed, and use emscripten to compile and run
[quick start of Digital IC Verification] 26. Ahb-sramc of SystemVerilog project practice (6) (basic points of APB protocol)
VS2005 strange breakpoint is invalid or member variable value cannot be viewed
居然从408改考自命题!211华北电力大学(北京)
Yunxiaoduo software internal test distribution test platform description document
Align individual elements to the right under flex layout
UE4 exports the picture + text combination diagram through ucanvasrendertarget2d
Zhongang Mining: Fluorite continues to lead the growth of new energy market
Syntaxhighlight highlights the right scroll bar
LeetCode3_ Longest substring without duplicate characters
Use cpolar to build a business website (2)
C Alibaba cloud OSS file upload, download and other operations (unity is available)
Whether runnable can be interrupted
Ue4/ue5 multi thread development attachment plug-in download address
Learn good-looking custom scroll bars in 1 minute