【发布时间】:2014-04-18 21:47:46
【问题描述】:
我正在使用 three.js 和所有示例(mrdoob、stemkoski)编写和动画循环,我看到在线在脚本开头使用了未受保护的全局变量。我试图将它们包含在 init() 函数中,然后通过动画循环将它们作为参数传递。但是,渲染器即将出现未定义。
我不确定我在下面缺少什么。我的主要问题是如何理解设置具有良好闭合的动画循环的最佳实践(保护否则将是全局的变量)。谢谢!
// THE MAIN ANIMATION LOOP:
// UPDATE the scene
function update(keyboard, controls, stats, clock) {
// delta = change in time since last call (in seconds)
var delta = clock.getDelta();
// functionality provided by THREEx.KeyboardState.js
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
stats.update();
};
// RENDER the scene
function render(renderer, scene, camera) {
renderer.render(scene, camera);
};
// ANIMATE the scene
function animate(scene, camera, renderer, controls, stats, keyboard, clock) {
requestAnimationFrame(animate);
render(renderer, scene, camera);
update(keyboard, controls, stats, clock);
};
// *********************
// INITIALIZES THE SCENE
function init(images) { // `images` is passed by a callback from loadImages
// standard global variables, held privately
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
///////////
// SCENE //
///////////
scene = new THREE.Scene();
////////////
// CAMERA //
////////////
// set the view size in pixels (custom or according to window size)
var SCREEN_WIDTH = 1920, SCREEN_HEIGHT = 1080;
// var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
// camera attributes
var VIEW_ANGLE = 20, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
// set up camera
camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
// add the camera to the scene
scene.add(camera);
// the camera defaults to position (0,0,0)
// so pull it back (z = 400) and up (y = 100) and set the angle towards the scene origin
// (x,y,z)
camera.position.set(0,150,1000);
camera.lookAt(scene.position);
//////////////
// RENDERER //
//////////////
// create and start the renderer; choose antialias setting.
if (Detector.webgl)
renderer = new THREE.WebGLRenderer( {antialias:true} );
else
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// attach div element to variable to contain the renderer
container = document.getElementById( 'ThreeJS' );
// attach renderer to the container div
container.appendChild( renderer.domElement );
///////////
// STATS //
///////////
// displays current and past frames per second attained by scene
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
///////////
// LIGHT //
///////////
// create a light
var light = new THREE.PointLight(0xffffff);
light.position.set(100,250,0);
scene.add(light);
////////////
// IMAGES //
////////////
var element1 = THREE.ImageUtils.loadTexture(images.dresser10);
var element2 = THREE.ImageUtils.loadTexture(images.dresser14);
var element1Material = new THREE.SpriteMaterial( { map: element1, useScreenCoordinates: true, alignment: THREE.SpriteAlignment.topLeft } );
var sprite = new THREE.Sprite(element1Material);
sprite.position.set( 50, 50, 0 );
sprite.scale.set( 64, 64, 1.0 ); // imageWidth, imageHeight
scene.add(sprite);
animate(container, scene, camera, renderer, controls, stats, keyboard, clock);
};
// ********************************************************
// CHECKS TO SEE IF THE WINDOW HAS LOADED BEFORE PROCEEDING
// Once the window is loaded, calls the init function
window.addEventListener ("load", eventWindowLoaded, false);
function eventWindowLoaded() {
loadImages(init); // calls to initialize the scene once the images are loaded
}
【问题讨论】:
-
如果你想避免全局变量,只需将整个脚本包装在一个模块 IEFE 中。
requestAnimationFrame(animate)不会传递任何参数。
标签: javascript animation three.js global-variables closures