tweenjs_for_smooth_animation.js | |
|---|---|
| This is the annotated source for this blog post. It is part of LearningThree.js blog. | |
Now lets start | |
| declare a bunch of variable we will need later | var startTime = Date.now();
var container;
var camera, scene, renderer, stats;
var cube; |
| maybe replace that by window... or something | var userOpts = {
range : 800,
duration : 2500,
delay : 200,
easing : 'Elastic.EaseInOut'
}; |
bootstrap functionsinitialiaze everything | init(); |
| make it move | animate(); |
========================= | |
Tween.js Setup (Start here) | |
========================= | function setupTween()
{ |
var update = function(){
cube.position.x = current.x;
}
var current = { x: -userOpts.range }; | |
| remove previous tweens if needed | TWEEN.removeAll();
|
| convert the string from dat-gui into tween.js functions | var easing = TWEEN.Easing[userOpts.easing.split('.')[0]][userOpts.easing.split('.')[1]]; |
| build the tween to go ahead | var tweenHead = new TWEEN.Tween(current)
.to({x: +userOpts.range}, userOpts.duration)
.delay(userOpts.delay)
.easing(easing)
.onUpdate(update); |
| build the tween to go backward | var tweenBack = new TWEEN.Tween(current)
.to({x: -userOpts.range}, userOpts.duration)
.delay(userOpts.delay)
.easing(easing)
.onUpdate(update); |
| after tweenHead do tweenBack | tweenHead.chain(tweenBack); |
| after tweenBack do tweenHead, so it is cycling | tweenBack.chain(tweenHead); |
| start the first | tweenHead.start();
} |
========================= | |
Tween.js Setup (End here) | |
========================= | |
Build gui with dat.gui | function buildGui(options, callback)
{ |
| collect all available easing in TWEEN library | var easings = {};
Object.keys(TWEEN.Easing).forEach(function(family){
Object.keys(TWEEN.Easing[family]).forEach(function(direction){
var name = family+'.'+direction;
easings[name] = name;
});
}); |
| the callback notified on UI change | var change = function(){
callback(options)
} |
| create and initialize the UI | var gui = new DAT.GUI({ height : 4 * 32 - 1 });
gui.add(options, 'range').name('Range coordinate').min(64).max(1280) .onChange(change);
gui.add(options, 'duration').name('Duration (ms)').min(100).max(4000) .onChange(change);
gui.add(options, 'delay').name('Delay (ms)').min(0).max(1000) .onChange(change);
gui.add(options, 'easing').name('Easing Curve').options(easings) .onChange(change);
} |
Initialize everything | function init() { |
| test if webgl is supported | if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); |
| create the camera | camera = new THREE.Camera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000; |
| create the Scene | scene = new THREE.Scene(); |
| build the GUI | buildGui(userOpts, function(){
console.log("userOpts", userOpts)
setupTween();
}); |
| initial setup of the tweens | setupTween(); |
| create the Cube | cube = new THREE.Mesh( new THREE.SphereGeometry( 200, 48, 32 ), new THREE.MeshNormalMaterial() );
cube.position.x = -userOpts.range; |
| add the object to the scene | scene.addObject( cube ); |
| create the container element | container = document.createElement( 'div' );
document.body.appendChild( container ); |
| init the WebGL renderer and append it to the Dom | renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
|
| init the Stats and append it to the Dom - performance vuemeter | stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
} |
Animate and Display the Scene | function animate() { |
| render the 3D scene | render(); |
| relaunch the 'timer' | requestAnimationFrame( animate ); |
| update the stats | stats.update(); |
| update the tweens from TWEEN library | TWEEN.update();
} |
Render the 3D Scene | function render() { |
| actually display the scene in the Dom element | renderer.render( scene, camera );
}
|