当前位置:网站首页>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
边栏推荐
- How to create Apple Developer personal account P8 certificate
- [deep learning] semantic segmentation experiment: UNET network /msrc2 dataset
- XMIND frame drawing tool
- 2022 all open source enterprise card issuing network repair short website and other bugs_ 2022 enterprise level multi merchant card issuing platform source code
- Android -- jetpack: the difference between livedata setValue and postvalue
- Summary of knowledge points of xlua hot update solution
- Unity's ASE realizes cartoon flame
- Use of SVN
- [quick start of Digital IC Verification] 25. AHB sramc of SystemVerilog project practice (5) (AHB key review, key points refining)
- Pit avoidance: description of null values in in and not in SQL
猜你喜欢
Asynchronous application of generator function
Create lib Library in keil and use lib Library
[quickstart to Digital IC Validation] 20. Basic syntax for system verilog Learning 7 (Coverage Driven... Including practical exercises)
Steps to create P8 certificate and warehousing account
numpy---基础学习笔记
Three. JS introductory learning notes 04: external model import - no material obj model
webgl_ Enter the three-dimensional world (2)
2022全开源企业发卡网修复短网址等BUG_2022企业级多商户发卡平台源码
AB package details in unity (super detail, features, packaging, loading, manager)
写一篇万字长文《CAS自旋锁》送杰伦的新专辑登顶热榜
随机推荐
OpenGL common functions
Nacos conformance protocol cp/ap/jraft/distro protocol
HPDC smart base Talent Development Summit essay
UE4 exports the picture + text combination diagram through ucanvasrendertarget2d
Learn good-looking custom scroll bars in 1 minute
It's different for rich people to buy a house
[wechat applet] Chapter (5): basic API interface of wechat applet
Yunxiaoduo software internal test distribution test platform description document
Cut ffmpeg as needed, and use emscripten to compile and run
Gd32 F3 pin mapping problem SW interface cannot be burned
How to deploy the super signature distribution platform system?
How to release NFT in batches in opensea (rinkeby test network)
postman生成时间戳,未来时间戳
【数字IC验证快速入门】24、SystemVerilog项目实践之AHB-SRAMC(4)(AHB继续深入)
[original] all management without assessment is nonsense!
Jacobo code coverage
Spin animation of Cocos performance optimization
Iterator and for of.. loop
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
Getting started with webgl (2)