简体   繁体   English

如何在Three.js中停止旋转

[英]How to stop rotation in three.js

Honorable coders, I use an html5 slideshow where I have added the rotating mesh landscape ( https://github.com/jeromeetienne/threex.terrain ). 尊敬的编码人员,我使用了html5幻灯片,其中添加了旋转的网格景观( https://github.com/jeromeetienne/threex.terrain )。 Because this animation slows down other part of the slideshow I want to shut it down when I move to the next slide. 由于此动画会减慢幻灯片显示的其他部分的速度,因此我想在移至下一张幻灯片时将其关闭。 I can call a function when the next slide is shown, however, I do not know how to shut down the rotation or simply stop the function. 当下一张幻灯片显示时,我可以调用一个函数,但是,我不知道如何关闭旋转或仅停止该函数。 I have tried removing the element 'front_id' that contains the rotating landscape but that does not seem to help and looking at the performance log the GPU is running crazy even when the element is deleted. 我尝试删除包含旋转景观的元素“ front_id”,但这似乎无济于事,并且查看性能日志,即使删除了该元素,GPU仍在运行。 Any solutions? 有什么办法吗?

My updated failed attempt: 我更新失败的尝试:

<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>

Thanks TheJim01 you are definitely right. 谢谢TheJim01,您绝对正确。 Not sure what I am doing wrong. 不知道我在做什么错。 Here I am defining the animationFrame variable globally but still I am unable to cancel it. 我在这里全局定义了animationFrame变量,但是仍然无法取消它。

Close, but not quite. 接近,但不完全是。 Look at what you have here: 看看这里有什么:

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);

You're assigning id_an with the ID of the first call to requestAnimationFrame , but you're not assigning it to IDs of the calls inside animate . 您要为id_an分配第一个requestAnimationFrame调用的ID,但没有将其分配给animate中的调用的ID。 Every call to requestAnimationFrame returns a unique ID, and you need to be able to cancel the most recent one to kill the loop. 每次requestAnimationFrame调用都返回一个唯一的ID,您需要取消最近的ID才能requestAnimationFrame循环。

Try this: 尝试这个:

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();

With this small change, id_an gets updated every frame with the latest ID, so when you call cancelAnimationFrame it will cancel the most recent one (which is the one you want to cancel). 有了这个很小的变化, id_an就会使用最新的ID更新每一帧,因此,当您调用cancelAnimationFrame ,它将取消最新的帧(这是您要取消的帧)。

Also, you don't need to call requestAnimationFrame to start the loop. 另外,您无需调用requestAnimationFrame即可开始循环。 Calling animate(); 调用animate(); at the end will get things rolling, including subsequent calls to requestAnimationFrame . 最后,事情将会滚动,包括随后对requestAnimationFrame调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM