首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >旋转到其他面的立方体不能使用three.js设置动画

问旋转到其他面的立方体不能使用three.js设置动画
EN

Stack Overflow用户
提问于 2019-12-23 17:41:27
回答 1查看 111关注 0票数 1

为什么下面的代码在旋转到另一个面上时不能为我的立方体添加动画?我该怎么解决它呢?

​

代码语言:javascript
复制
new Vue({
  el: '#app',
  data () {
    return {
      camera: null,
      scene: null,
      renderer: null,
      mesh: null,
      rotationPerc: 0
    }
  },
  methods: {
    init: function () {
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
      });
      let container = document.getElementById('container');
      container.appendChild(this.renderer.domElement);
      this.camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
      this.camera.position.z = 400;

      // Make a scene
      this.scene = new THREE.Scene();

      // 1. Start with empty geometry
      let geometry = new THREE.Geometry();

      // 2. Add vertices to geometry
      geometry.vertices.push(
        // verts [0-3] are in in +z
        new THREE.Vector3(-100, 100, 100),
        new THREE.Vector3(-100, -100, 100),
        new THREE.Vector3(100, -100, 100),
        new THREE.Vector3(100, 100, 100),
        // verts [4-7] in -z
        new THREE.Vector3(-100, 100, -100),
        new THREE.Vector3(-100, -100, -100),
        new THREE.Vector3(100, -100, -100),
        new THREE.Vector3(100, 100, -100),
      );

      // 3. Connect vertices in desired order to make faces
      let b = 0x1db0ec
      let y = 0xffef3a
      let r = 0xea353d
      let w = 0xffffff
      //
      geometry.faces.push(new THREE.Face3(0, 1, 2)); // blue
      geometry.faces.push(new THREE.Face3(0, 2, 3)); // yellow
      geometry.faces.push(new THREE.Face3(5, 4, 6)); // white
      geometry.faces.push(new THREE.Face3(6, 4, 7)); // red
      //
      geometry.faces.push(new THREE.Face3(1, 0, 5)); // blue
      geometry.faces.push(new THREE.Face3(5, 0, 4));
      geometry.faces.push(new THREE.Face3(1, 5, 2)); // white
      geometry.faces.push(new THREE.Face3(5, 6, 2));
      geometry.faces.push(new THREE.Face3(2, 6, 3)); // red
      geometry.faces.push(new THREE.Face3(3, 6, 7));
      geometry.faces.push(new THREE.Face3(0, 3, 4)); // yellow
      geometry.faces.push(new THREE.Face3(3, 7, 4));
      //
      geometry.faces[0].color.setHex(b);
      geometry.faces[1].color.setHex(y);
      geometry.faces[2].color.setHex(w);
      geometry.faces[3].color.setHex(r);
      //
      geometry.faces[4].color.setHex(b);
      geometry.faces[5].color.setHex(b);
      geometry.faces[6].color.setHex(w);
      geometry.faces[7].color.setHex(w);
      geometry.faces[8].color.setHex(r);
      geometry.faces[9].color.setHex(r);
      geometry.faces[10].color.setHex(y);
      geometry.faces[11].color.setHex(y);

      // Make a material
      let material = new THREE.MeshBasicMaterial({
        // color: 0x00FF00,
        vertexColors: THREE.FaceColors,
        wireframe: false,
      });

      // Create a mesh based on the geometry and material
      this.mesh = new THREE.Mesh(geometry, material);
      this.scene.add(this.mesh);

    },
    rotateTo: function (face) {
      if (face == 'yellow')
        this.mesh.rotation.set(0, Math.PI / 2 * this.rotationPerc, Math.PI / 2 * this.rotationPerc);
      else if (face == 'red')
        this.mesh.rotation.set(Math.PI / 2 * this.rotationPerc, 0, Math.PI / 2 * this.rotationPerc);
      else if (face == 'blue')
        this.mesh.rotation.set(Math.PI / 2 * this.rotationPerc, 0, - Math.PI / 2 * this.rotationPerc);
      else if (face == 'white')
        this.mesh.rotation.set(- Math.PI / 2 * this.rotationPerc, Math.PI / 2 * this.rotationPerc, 0);
      else if (face == 'yb')
        this.mesh.rotation.set(0, 0, 0);
      else if (face == 'rw')
        this.mesh.rotation.set(Math.PI * this.rotationPerc, 0, 0);

      this.renderer.render(this.scene, this.camera);

      if (this.rotationPerc < 1) {
        this.rotationPerc += 0.001
        this.rotateTo(face)
      } else {
        this.rotationPerc = 1
      }
    }
  },
  mounted () {
    this.init();
    this.renderer.render(this.scene, this.camera);
  }
})
代码语言:javascript
复制
#app {
  padding: 0.1em;
  background-color: #eff0f1;
}
代码语言:javascript
复制
<script src="https://unpkg.com/vue"></script>
<script src="https://threejs.org/build/three.min.js"></script>

<div id="app">
    <div>
      <button v-on:click="rotateTo('yellow')">yellow</button>
      <button v-on:click="rotateTo('red')">red</button>
      <button v-on:click="rotateTo('blue')">blue</button>
      <button v-on:click="rotateTo('white')">white</button>
      <button v-on:click="rotateTo('yb')">yellow/blue</button>
      <button v-on:click="rotateTo('rw')">red/white</button>
    </div>
    <div id="container"></div>
</div>

​

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-23 22:09:58

当在交互式2D/3D应用程序中动画对象时,建议使用动画循环。您在没有任何延迟的情况下执行更改,因此转换发生得非常快。此外,建议在设置旋转动画时避免使用euler角度。请改用四元数。three.js提供了一种Quaternion.rotateTowards()方法,非常适合您的用例。第一个参数定义目标旋转,第二个参数定义以弧度为单位的角步长。这意味着它会逐渐将对象旋转到定义的目标旋转。这类似于Unity的Quaternion.RotateTowards的工作原理。three.js实现还将确保对象不会“超调”。

将以下两行放入动画循环中:

代码语言:javascript
复制
var delta = clock.getDelta(); // clock is an instance of THREE.Clock

mesh.quaternion.rotateTowards( targetRotation, step * delta );

step以秒为单位定义角度位移。请查看以下小提琴以获取完整的示例:

https://jsfiddle.net/hx06vn8p/1/

three.js R111

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59453058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档