在下面的代码中,多维数据集有时随动画一起移动,有时不随动画一起移动。我该如何解决?
另外,我应该如何设置转速?
new Vue({
el: '#app',
data () {
return {
camera: null,
scene: null,
renderer: null,
cube: null,
angle: null
}
},
methods: {
init: function () {
this.camera = new THREE.PerspectiveCamera(1, 1);
this.camera.position.z = 200;
// Make a scene
this.scene = new THREE.Scene();
this.clock = new THREE.Clock();
//
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
let container = document.getElementById('container')
this.renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(this.renderer.domElement);
let cube2 = this.createCube()
cube2.name = "cube2"
// cube2.position = new THREE.Vector3(1, 0)
this.scene.add(cube2);
},
createCube: function () {
// GEOMETRY
// 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(-1, 1, 1),
new THREE.Vector3(-1, -1, 1),
new THREE.Vector3(1, -1, 1),
new THREE.Vector3(1, 1, 1),
// verts [4-7] in -z
new THREE.Vector3(-1, 1, -1),
new THREE.Vector3(-1, -1, -1),
new THREE.Vector3(1, -1, -1),
new THREE.Vector3(1, 1, -1),
);
// 3. Connect vertices in desired order to make faces
let b = 0x1db0ec
let y = 0xffef3a
let r = 0xea353d
let w = 0xffffff
// Set half faces
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
// Set whole faces
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));
// Set faces colors
geometry.faces[0].color.setHex(b); // Half face
geometry.faces[1].color.setHex(y);
geometry.faces[2].color.setHex(w);
geometry.faces[3].color.setHex(r);
geometry.faces[4].color.setHex(b); // Whole face
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);
// MATERIAL
// Make a material
let material = new THREE.MeshBasicMaterial({
// color: 0x00FF00,
vertexColors: THREE.FaceColors,
wireframe: false,
});
// MESH
let cube = new THREE.Mesh(geometry, material);
return cube
},
rotateTo: function (face) {
if (face == 'yellow')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI / 2, Math.PI / 2));
else if (face == 'red')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI / 2, 0, Math.PI / 2));
else if (face == 'blue')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI / 2, 0, - Math.PI / 2));
else if (face == 'white')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(- Math.PI / 2, Math.PI / 2, 0));
else if (face == 'yb')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, 0));
else if (face == 'rw')
this.angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI, 0, 0));
this.animate()
},
animate: function () {
let id = requestAnimationFrame(this.animate);
let delta = this.clock.getDelta();
this.scene.children[0].quaternion.rotateTowards(this.angle, Math.PI * delta);
this.renderer.render(this.scene, this.camera);
if (this.scene.children[0].quaternion.equals(this.angle)) {
cancelAnimationFrame(id)
}
}
},
mounted () {
this.init();
this.renderer.render(this.scene, this.camera);
}
})
#container {
background-color: #aaa;
width: 20em;
height: 20em;
}
<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>
仅隔离到threejs部分的代码。
var camera = null;
var scene = null;
var renderer = null;
var cube = null;
var angle = null;
init();
renderer.render(scene, camera);
function init() {
camera = new THREE.PerspectiveCamera(1, 1);
camera.position.z = 200;
// Make a scene
scene = new THREE.Scene();
clock = new THREE.Clock();
//
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
let container = document.getElementById('container');
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);
let cube2 = createCube();
cube2.name = "cube2";
// cube2.position = new THREE.Vector3(1, 0)
scene.add(cube2);
}
function createCube() {
// GEOMETRY
// 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(-1, 1, 1),
new THREE.Vector3(-1, -1, 1),
new THREE.Vector3(1, -1, 1),
new THREE.Vector3(1, 1, 1),
// verts [4-7] in -z
new THREE.Vector3(-1, 1, -1),
new THREE.Vector3(-1, -1, -1),
new THREE.Vector3(1, -1, -1),
new THREE.Vector3(1, 1, -1),
);
// 3. Connect vertices in desired order to make faces
let b = 0x1db0ec;
let y = 0xffef3a;
let r = 0xea353d;
let w = 0xffffff;
// Set half faces
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
// Set whole faces
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));
// Set faces colors
geometry.faces[0].color.setHex(b); // Half face
geometry.faces[1].color.setHex(y);
geometry.faces[2].color.setHex(w);
geometry.faces[3].color.setHex(r);
geometry.faces[4].color.setHex(b); // Whole face
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);
// MATERIAL
// Make a material
let material = new THREE.MeshBasicMaterial({
// color: 0x00FF00,
vertexColors: THREE.FaceColors,
wireframe: false,
});
// MESH
let cube = new THREE.Mesh(geometry, material);
return cube;
}
function rotateTo(face) {
if (face == 'yellow')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI / 2, Math.PI / 2));
else if (face == 'red')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI / 2, 0, Math.PI / 2));
else if (face == 'blue')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI / 2, 0, -Math.PI / 2));
else if (face == 'white')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(-Math.PI / 2, Math.PI / 2, 0));
else if (face == 'yb')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, 0));
else if (face == 'rw')
angle = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI, 0, 0));
animate();
}
function animate() {
let id = requestAnimationFrame(animate);
let delta = clock.getDelta();
scene.children[0].quaternion.rotateTowards(angle, Math.PI * delta);
renderer.render(scene, camera);
if (scene.children[0].quaternion.equals(angle)) {
cancelAnimationFrame(id);
}
}
#container {
background-color: #aaa;
width: 20em;
height: 20em;
}
<script src="https://threejs.org/build/three.min.js"></script>
<div>
<button onclick="rotateTo('yellow')">yellow</button>
<button onclick="rotateTo('red')">red</button>
<button onclick="rotateTo('blue')">blue</button>
<button onclick="rotateTo('white')">white</button>
<button onclick="rotateTo('yb')">yellow/blue</button>
<button onclick="rotateTo('rw')">red/white</button>
</div>
<div id="container"></div>
答案 0 :(得分:2)
动画不播放的原因是,当您cancelAnimationFrame
时钟仍在运行时,因此下次调用rotateTo
时,增量如此之高,动画立即结束。
您可以通过使用cancelAnimationFrame
停止时钟并在调用rotateTo
时重新启动时钟来避免这种情况,如下所示:
function rotateTo(face) {
clock.start()
...
}
function animate() {
...
if (scene.children[0].quaternion.equals(angle)) {
cancelAnimationFrame(id);
clock.stop()
}
}
关于转速,rotateTowards
的第二个arg是step,它确定到达那里的速度。因此,如果向其添加修饰符var,则可以控制速度。
let rotSpeedMotifier = 0.2 // the higher the faster
scene.children[0].quaternion.rotateTowards(angle, Math.PI * delta * rotSpeedMotifier );