【问题标题】:Web animation speeds up with each use每次使用都会加快网络动画的速度
【发布时间】:2020-01-03 23:53:12
【问题描述】:

对于一个练习,我应该创建一本由箭头键控制的书,并且在没有按键时平稳停止。但是,每次单击箭头键时,动画播放的速度都会越来越快。

我将下面的代码粘贴,抱歉没有将其限制在必要的部分,但我自己并没有完全理解。

var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;

document.addEventListener('keydown', onDocumentKeyDown, false);
document.addEventListener('keyup', onDocumentKeyUp, false);

function onDocumentKeyDown(event) {
  event = event || window.event;
  var keycode = event.keyCode;

  switch (keycode) {

    case 38:
      tb -= 5;
      break;
    case 40:
      tb += 5;
      break;

    case 37:
      t -= 5;
      break;
    case 39:
      t += 5;
      break;

  }
}


function onDocumentKeyUp(event) {
  event = event || window.event;
  var keycode = event.keyCode;


  requestAnimationFrame(render);


  cube.position.x += 0 * Math.sin(t);
  renderer.render(scene, camera);


  switch (keycode) {



    case 37:
      console.log("left up");
      break;
    case 38:
      console.log("up up");
      break;
    case 39:
      console.log("right up");
      break;
    case 40:
      console.log("down up");
      break;
  }
}

var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0xDDDDDD, 1);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(50, WIDTH / HEIGHT, 0.1, 10000);
camera.position.z = 50;
scene.add(camera);

var boxGeometry = new THREE.BoxGeometry(10, 10, 10);
var phongMaterial = new THREE.MeshPhongMaterial({
  color: 0xFF0000
});
var cube = new THREE.Mesh(boxGeometry, phongMaterial);
cube.position.x = -25;
cube.rotation.set(0.4, 0.2, 1);
scene.add(cube);

var light = new THREE.PointLight(0xFFFFFF);
light.position.set(-10, 15, 50);
scene.add(light);

var t = 0;
var tb = 0;

function render() {
  if (t > 0) t *= 0.98;
  if (t < 0) t *= 0.98;
  if (t > 0 && t < 0.5) t = 0;
  if (t < 0 && t > (-0.5)) t = 0;

  if (tb > 0) tb *= 0.98;
  if (tb < 0) tb *= 0.98;
  if (tb > 0 && tb < 0.5) tb = 0;
  if (tb < 0 && tb > (-0.5)) tb = 0;

  requestAnimationFrame(render);

  if (t != 0) console.log(t);

  cube.position.x += 0.1 * t;
  cube.position.z += 0.1 * tb;
  renderer.render(scene, camera);
}
render();
body {
  margin: 0;
  padding: 0;
  font-size: 0;
}

canvas {
  width: 100%;
  height: 100%;
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"&gt;&lt;/script&gt;

【问题讨论】:

    标签: javascript html arrays three.js


    【解决方案1】:

    从键侦听器中删除 requestAnimationFrame(render)。 render 函数已经在循环中运行,因此再次调用它会导致该函数的多个版本同时运行。调用 renderer.render(scene, camera); 也是如此——这应该只在一个地方调用。

    提示:更新键侦听器内部的t/tb(这些变量名称可能更清晰...)在键重新触发时会导致异常行为。要获得更可预测和更流畅的键盘操作,让按键侦听器只需打开和关闭每个按键的布尔值,然后让渲染循环处理对 t 和 tb 的更改。

    另一个一般建议是避免在渲染循环中硬编码值。这样做的问题是原始值没有语义含义,并且随着代码的增长,它变得容易出错并且难以更改它们。理想情况下,创建一个配置对象,将这些值以适当的名称(acceleration、damping 等)存储在一个位置。我会把它留作练习。

    var WIDTH = window.innerWidth;
    var HEIGHT = window.innerHeight;
    var keyMap = {37: "l", 38: "u", 39: "r", 40: "d"};
    var keys = {};
    
    document.addEventListener("keydown", function (e) {
      e = e || window.event;
      keys[keyMap[e.keyCode]] = true;
    }, false);
    document.addEventListener("keyup", function (e) {
      e = e || window.event;
      keys[keyMap[e.keyCode]] = false;
    }, false);
    
    var renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(WIDTH, HEIGHT);
    renderer.setClearColor(0xDDDDDD, 1);
    document.body.appendChild(renderer.domElement);
    
    var scene = new THREE.Scene();
    
    var camera = new THREE.PerspectiveCamera(50, WIDTH / HEIGHT, 0.1, 10000);
    camera.position.z = 50;
    scene.add(camera);
    
    var boxGeometry = new THREE.BoxGeometry(10, 10, 10);
    var phongMaterial = new THREE.MeshPhongMaterial({
      color: 0xFF0000
    });
    var cube = new THREE.Mesh(boxGeometry, phongMaterial);
    cube.position.x = -25;
    cube.rotation.set(0.4, 0.2, 1);
    scene.add(cube);
    
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.set(-10, 15, 50);
    scene.add(light);
    
    var t = 0;
    var tb = 0;
    
    function render() {
      if (keys.u) tb -= 5;
      if (keys.d) tb += 5;
      if (keys.r) t += 5;
      if (keys.l) t -= 5;
    
      if (t > 0) t *= 0.98;
      if (t < 0) t *= 0.98;
      if (t > 0 && t < 0.5) t = 0;
      if (t < 0 && t > (-0.5)) t = 0;
    
      if (tb > 0) tb *= 0.98;
      if (tb < 0) tb *= 0.98;
      if (tb > 0 && tb < 0.5) tb = 0;
      if (tb < 0 && tb > (-0.5)) tb = 0;
    
      cube.position.x += 0.1 * t;
      cube.position.z += 0.1 * tb;
      renderer.render(scene, camera);
      requestAnimationFrame(render);
    }
    
    render();
    body {
      margin: 0;
      padding: 0;
    }
    
    canvas {
      width: 100%;
      height: 100%;
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 感谢您的精心回复!我会尝试实现你提到的一些东西,看看效果如何。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2017-05-14
    • 2010-12-08
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多