ThreeJS 吐温JS |平滑地移动和旋转相机到物体
ThreeJS Tween JS | Move AND Rotate the camera to an object smoothly
当我点击一个对象时,我可以围绕它移动和旋转。
这是非平滑代码:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Look at the object and rotate around it
this.controls.target.set( intersects[i].point.x, intersects[i].point.y, intersects[i].point.z )
// Move to the object
this.camera.position.x = intersects[i].point.x
this.camera.position.y = intersects[i].point.y
this.camera.position.z = (intersects[i].point.z) + 1000
}
})
}
现在我想做完全相同的旋转,但旋转和移动平稳。在网上看了一堆之后,我找到了 TweenJS 并使用了它。 问题是我可以顺畅地向物体移动,但我不知道如何顺畅地看着物体并绕着它旋转。
下面是流畅的代码:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Look at the object and rotate around it smoothly (using tweenjs I suppose)
????????????
// Move to the object smoothly
var position = this.camera.position;
var target = { x : intersects[i].point.x, y: intersects[i].point.y, z: intersects[i].point.z + 1000 };
var tween = new TWEEN.Tween(position).to(target, 2000);
tween.easing(TWEEN.Easing.Linear.None)
tween.start()
}
})
}
您可能需要在渲染循环或补间自定义更新函数中的某处添加 camera.lookAt( yourTargetPoint )。
var target = new THREE.Vector3()
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
target.copy(intersects[i].point)
var tween = new TWEEN.Tween(this.camera.position).to(target, 2000)
tween.easing(TWEEN.Easing.Linear.None)
tween.onUpdate(() => {
this.camera.lookAt( target )
})
tween.start()
break; // BREAK HERE BECAUSE WE ONLY CARE ABOUT THE FIRST/AKA NEAREST COLLISION
}
})
}
您还需要确保将相机添加到场景中。您可以使用 ISNT 连接到场景的相机进行渲染,但其矩阵不会在渲染阶段更新,在这种情况下,您必须调用 .updateMatrixWorld() 来强制更新其矩阵。但是只 scene.add(camera)
更容易
我找到了另一个解决方案。我使用了 2 个不同的补间,1 个用于移动相机,1 个用于使相机注视对象。
代码如下:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Move the camera towards the object and stay 1000 above it on z axis
var positionX = intersects[i].point.x
var positionY = intersects[i].point.y
var positionZ = (intersects[i].point.z) + 1000
var positionStart = this.camera.position
var positionEnd = { x : positionX, y: positionY, z: positionZ }
var tweenPosition = new TWEEN.Tween(positionStart).to(positionEnd, 2000)
tweenPosition.easing(TWEEN.Easing.Linear.None)
tweenPosition.start()
// Make the camera look at the object
var rotationX = intersects[i].point.x
var rotationY = intersects[i].point.y
var rotationZ = intersects[i].point.z
var rotationStart = this.controls.target
var rotationEnd = { x : rotationX, y: rotationY, z: rotationZ }
var tweenRotation = new TWEEN.Tween(rotationStart).to(rotationEnd, 2000)
tweenRotation.easing(TWEEN.Easing.Linear.None)
tweenRotation.start()
}
})
}
当我点击一个对象时,我可以围绕它移动和旋转。
这是非平滑代码:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Look at the object and rotate around it
this.controls.target.set( intersects[i].point.x, intersects[i].point.y, intersects[i].point.z )
// Move to the object
this.camera.position.x = intersects[i].point.x
this.camera.position.y = intersects[i].point.y
this.camera.position.z = (intersects[i].point.z) + 1000
}
})
}
现在我想做完全相同的旋转,但旋转和移动平稳。在网上看了一堆之后,我找到了 TweenJS 并使用了它。 问题是我可以顺畅地向物体移动,但我不知道如何顺畅地看着物体并绕着它旋转。
下面是流畅的代码:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Look at the object and rotate around it smoothly (using tweenjs I suppose)
????????????
// Move to the object smoothly
var position = this.camera.position;
var target = { x : intersects[i].point.x, y: intersects[i].point.y, z: intersects[i].point.z + 1000 };
var tween = new TWEEN.Tween(position).to(target, 2000);
tween.easing(TWEEN.Easing.Linear.None)
tween.start()
}
})
}
您可能需要在渲染循环或补间自定义更新函数中的某处添加 camera.lookAt( yourTargetPoint )。
var target = new THREE.Vector3()
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
target.copy(intersects[i].point)
var tween = new TWEEN.Tween(this.camera.position).to(target, 2000)
tween.easing(TWEEN.Easing.Linear.None)
tween.onUpdate(() => {
this.camera.lookAt( target )
})
tween.start()
break; // BREAK HERE BECAUSE WE ONLY CARE ABOUT THE FIRST/AKA NEAREST COLLISION
}
})
}
您还需要确保将相机添加到场景中。您可以使用 ISNT 连接到场景的相机进行渲染,但其矩阵不会在渲染阶段更新,在这种情况下,您必须调用 .updateMatrixWorld() 来强制更新其矩阵。但是只 scene.add(camera)
更容易我找到了另一个解决方案。我使用了 2 个不同的补间,1 个用于移动相机,1 个用于使相机注视对象。
代码如下:
mouseEvents() {
window.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
// Get the mouse position
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
this.raycaster.setFromCamera(this.mouse, this.camera)
var intersects = this.raycaster.intersectObjects(this.scene.children, true)
for (var i=0; i<intersects.length; i++) {
// Move the camera towards the object and stay 1000 above it on z axis
var positionX = intersects[i].point.x
var positionY = intersects[i].point.y
var positionZ = (intersects[i].point.z) + 1000
var positionStart = this.camera.position
var positionEnd = { x : positionX, y: positionY, z: positionZ }
var tweenPosition = new TWEEN.Tween(positionStart).to(positionEnd, 2000)
tweenPosition.easing(TWEEN.Easing.Linear.None)
tweenPosition.start()
// Make the camera look at the object
var rotationX = intersects[i].point.x
var rotationY = intersects[i].point.y
var rotationZ = intersects[i].point.z
var rotationStart = this.controls.target
var rotationEnd = { x : rotationX, y: rotationY, z: rotationZ }
var tweenRotation = new TWEEN.Tween(rotationStart).to(rotationEnd, 2000)
tweenRotation.easing(TWEEN.Easing.Linear.None)
tweenRotation.start()
}
})
}