如何在three.js中停止旋转

时间:2018-01-24 14:35:19

标签: javascript three.js

尊敬的程序员,我使用html5幻灯片放映,我添加了旋转网格景观(https://github.com/jeromeetienne/threex.terrain)。因为这个动画减慢了幻灯片放映的其他部分,所以当我移动到下一张幻灯片时,我希望将其关闭。我可以在显示下一张幻灯片时调用一个函数,但是,我不知道如何关闭旋转或只是停止该功能。我已经尝试删除包含旋转横向的元素'front_id',但这似乎没有帮助,并且即使在删除元素时,GPU也在查看性能日志。任何解决方案?

我更新失败的尝试:

<script type="text/javascript">

var id_an;

function run_land(){

var renderer  = new THREE.WebGLRenderer({
  antialias : true
});
renderer.setSize( window.innerWidth+600, window.innerHeight );
var the_dom = renderer.domElement;
the_dom.id = 'land_id';
document.getElementById('front_id').appendChild(the_dom);
var onRenderFcts= [];
var scene = new THREE.Scene();
var camera  = new THREE.PerspectiveCamera(25, 
window.innerWidth/window.innerHeight, 0.01, 1000);
camera.position.z = 15; 
camera.position.y = 2;
scene.fog = new THREE.Fog(0x565656, 10, 45);
;(function(){
  var light = new THREE.AmbientLight( 0x202020 );
  scene.add( light );
  var light = new THREE.DirectionalLight('white', 5);
  light.position.set(0.5, 0.0, 2);
  scene.add( light );
  var light = new THREE.DirectionalLight('white', 0.75*2);
  light.position.set(-0.5, -0.5, -2);
  scene.add( light );
})()
var heightMap = THREEx.Terrain.allocateHeightMap(512,256);
THREEx.Terrain.simplexHeightMap(heightMap);
var geometry  = THREEx.Terrain.heightMapToPlaneGeometry(heightMap);
THREEx.Terrain.heightMapToVertexColor(heightMap, geometry);
var material  = new THREE.MeshBasicMaterial({
  wireframe: true
});
var mesh  = new THREE.Mesh( geometry, material );
mesh.name = 'the_mesh_name';
scene.add( mesh );
mesh.lookAt(new THREE.Vector3(0,1,0));
mesh.scale.y  = 4.5;
mesh.scale.x  = 5;
mesh.scale.z  = 0.30;
mesh.scale.multiplyScalar(10);
onRenderFcts.push(function(delta, now){
  mesh.rotation.z += 0.2 * delta; 
})

onRenderFcts.push(function(){
  renderer.render( scene, camera );   
})
var lastTimeMsec= null;
function animate(nowMsec){
  requestAnimationFrame( animate );
  lastTimeMsec  = lastTimeMsec || nowMsec-1000/60;
  var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
  lastTimeMsec  = nowMsec;
  onRenderFcts.forEach(function(onRenderFct){
    onRenderFct(deltaMsec/5000, nowMsec/5000);
  });  
}
id_an = requestAnimationFrame(animate);
}

var end_landscapes = (function() {
  return function() {

  console.log("the id: "+id_an); //this always returns id_an = 4
  cancelAnimationFrame(id_an);
  };

})();

</script>

谢谢TheJim01,你绝对是对的。不确定我做错了什么。这里我是全局定义animationFrame变量,但我仍然无法取消它。

1 个答案:

答案 0 :(得分:1)

关闭,但不完全。看看你在这里有什么:

function animate(nowMsec) {
  requestAnimationFrame(animate);
  lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60;
  var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
  lastTimeMsec = nowMsec;
  onRenderFcts.forEach(function(onRenderFct) {
    onRenderFct(deltaMsec / 5000, nowMsec / 5000);
  });
}
id_an = requestAnimationFrame(animate);

您已将id_an第一次电话号码分配给requestAnimationFrame,但您并未将其分配给内部电话的ID animaterequestAnimationFrame的每次调用都会返回一个唯一的ID,您需要能够取消最近的ID才能终止该循环。

试试这个:

function animate(nowMsec) {
  id_an = requestAnimationFrame(animate);
  lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60;
  var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
  lastTimeMsec = nowMsec;
  onRenderFcts.forEach(function(onRenderFct) {
    onRenderFct(deltaMsec / 5000, nowMsec / 5000);
  });
}
animate();

通过这一小改动,id_an每帧都会使用最新ID进行更新,因此当您拨打cancelAnimationFrame时,它会取消最近的一个(您要取消的那个)。< / p>

此外,您不需要致电requestAnimationFrame来启动循环。最后调用animate();会让事情滚动,包括后续调用requestAnimationFrame