Three.js - 如何缓慢改变相机的方向直到它到达一个特定的向量
Three.js - How to slowly change the camera's orientation untill it reaches a specific vector
我正在使用Three.js开发一个360°图片的播放器,我需要一些建议。
我在场景中创建了一些可关联的网格。当前,当用户单击网格时,相机的方向会粗暴地更改为网格的方向。 (这是通过调用 THREE.Camera.lookat() 完成的)。
我想要的是当用户点击时,相机从它的目标向量平滑地过渡到网格的方向。我希望相机从当前矢量到网格方向大约需要 1 秒。
我看到 tween 是一个我们可以用它来制作场景动画的库,但我并没有真正理解它是如何工作的。
你知道我可以用什么来实现这个动画吗?
如果 tween 可以帮助我,你能解释一下 tween 如何与 three.js 一起发挥作用,或者你能 link 一些 githubs 或者其他吗?
感谢您的反馈。
类似于:
var targetRotation,startTime,transitionDuration;
var startRotation = camera.quaternion.clone();
function smoothTransition(newTarget){
startRotation.copy(camera.quaternion);
camera.lookAt(newTarget);
camera.updateMatrixWorld();
targetRotation = camera.rotation.clone();
startTime = performance.now();
transitionDuration = 1000;
}
在动画中:
if(startRotation){
var playTime = (performance.now()-startTime)/transitionDuration;
if(playTime>1)playTime = 1;
Quaternion.slerp(startRotation,targetRotation,camera.rotation,playTime);
camera.updateMatrixWorld();
}
Tween.js
只是 manthrax 思想的延伸
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
color: "yellow",
wireframe: true
}));
scene.add(sphere);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var startRotation = new THREE.Quaternion();
var targetRotation = new THREE.Quaternion();
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let newPosition = raycaster.ray.at(10);
setPoint(newPosition);
// manthrax's idea + Tween.js
startRotation.copy(camera.quaternion);
camera.lookAt(newPosition);
camera.updateMatrixWorld();
targetRotation = camera.quaternion.clone();
camera.quaternion.copy(startRotation);
new TWEEN.Tween(camera.quaternion).to(targetRotation, 1000).easing(TWEEN.Easing.Bounce.Out).delay(250).start();
// one of benefits of using Tween.js is easings
// you can find many of them here
// https://sole.github.io/tween.js/examples/03_graphs.html
}
function setPoint(position) {
let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
point.position.copy(position);
scene.add(point);
}
render()
function render() {
requestAnimationFrame(render);
TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
我正在使用Three.js开发一个360°图片的播放器,我需要一些建议。
我在场景中创建了一些可关联的网格。当前,当用户单击网格时,相机的方向会粗暴地更改为网格的方向。 (这是通过调用 THREE.Camera.lookat() 完成的)。
我想要的是当用户点击时,相机从它的目标向量平滑地过渡到网格的方向。我希望相机从当前矢量到网格方向大约需要 1 秒。
我看到 tween 是一个我们可以用它来制作场景动画的库,但我并没有真正理解它是如何工作的。 你知道我可以用什么来实现这个动画吗? 如果 tween 可以帮助我,你能解释一下 tween 如何与 three.js 一起发挥作用,或者你能 link 一些 githubs 或者其他吗?
感谢您的反馈。
类似于:
var targetRotation,startTime,transitionDuration;
var startRotation = camera.quaternion.clone();
function smoothTransition(newTarget){
startRotation.copy(camera.quaternion);
camera.lookAt(newTarget);
camera.updateMatrixWorld();
targetRotation = camera.rotation.clone();
startTime = performance.now();
transitionDuration = 1000;
}
在动画中:
if(startRotation){
var playTime = (performance.now()-startTime)/transitionDuration;
if(playTime>1)playTime = 1;
Quaternion.slerp(startRotation,targetRotation,camera.rotation,playTime);
camera.updateMatrixWorld();
}
Tween.js
只是 manthrax 思想的延伸var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
color: "yellow",
wireframe: true
}));
scene.add(sphere);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var startRotation = new THREE.Quaternion();
var targetRotation = new THREE.Quaternion();
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let newPosition = raycaster.ray.at(10);
setPoint(newPosition);
// manthrax's idea + Tween.js
startRotation.copy(camera.quaternion);
camera.lookAt(newPosition);
camera.updateMatrixWorld();
targetRotation = camera.quaternion.clone();
camera.quaternion.copy(startRotation);
new TWEEN.Tween(camera.quaternion).to(targetRotation, 1000).easing(TWEEN.Easing.Bounce.Out).delay(250).start();
// one of benefits of using Tween.js is easings
// you can find many of them here
// https://sole.github.io/tween.js/examples/03_graphs.html
}
function setPoint(position) {
let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
point.position.copy(position);
scene.add(point);
}
render()
function render() {
requestAnimationFrame(render);
TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>