效果图:
1.点击前
2.点击后
说明:效果就是我在给模型打标签时保存视角和坐标,点击标签的时候读取到坐标数据,再转动到对应视角。
1.安装 TWEEN
npm install --save @tweenjs/tween.js
2.在当前页引入
import TWEEN from "@tweenjs/tween.js";
3.添加标注时,将添加标注时的相机视角与模型的坐标进行保存(添加标注的逻辑在我之前的博客)
// 创建标签
createLableObj (text, vector) {
let laberDiv = document.createElement('div');//创建div容器
laberDiv.className = 'laber_name';
// laberDiv.textContent = text;
laberDiv.innerHTML = `
<div class='label_count'>
<span class='close'>X</span>
${
text}
</div>
`
// 给标签设置坐标位置
laberDiv.setAttribute("data-point", JSON.stringify(camera.position))
laberDiv.setAttribute("data-place", JSON.stringify(this.controls.target))
let pointLabel = new CSS2DObject(laberDiv);
pointLabel.position.set(vector.x, vector.y, vector.z);
return pointLabel;
},
4.监听标签点击事件,
// 监听标签盒子内的标签点击事件
let _this = this;
document.getElementsByClassName("allLabel")[0].addEventListener('click', function (e) {
// 选中当前标签时显示详情
if (e.target.className == "laber_name") {
// 获取标签的坐标
let labelPoint = JSON.parse(e.target.getAttribute("data-point"));
// 获取创建标签时的中心点
let labelPlace = JSON.parse(e.target.getAttribute("data-place"));
// let newControlsPoint = { x: 0, y: 0, z: 0 },//中心点为场景中间
_this.animateCamera(camera.position, _this.controls.target, labelPoint, labelPlace, e)
}
// 点击取消时隐藏标签详情
if (e.target.className == 'close') {
// 回到初始状态
_this.initPoint()
}
}, true)
5.坐标过渡
// 模型角度变化函数
animateCamera (oldP, oldC, newP, newC, e) {
let _this = this;
var p1 = {
x1: oldP.x,
y1: oldP.y,
z1: oldP.z,
x2: oldC.x,
y2: oldC.y,
z2: oldC.z,
}
var p2 = {
x1: newP.x,
y1: newP.y,
z1: newP.z,
x2: newC.x,
y2: newC.y,
z2: newC.z,
}
var tween = new TWEEN.Tween(p1).to(p2, 1800);//第一段动画
var update = function (object) {
camera.position.set(object.x1, object.y1, object.z1);
_this.controls.target.set(object.x2, object.y2, object.z2);
camera.lookAt(0, 0, 0);//保证动画执行时,相机焦距在中心点
_this.controls.enabled = false;
_this.controls.update();
};
tween.onUpdate(update);
// 动画完成后的执行函数
tween.onComplete(() => {
_this.controls.enabled = true; //执行完成后开启控制
//这一段是为了实现点击标签时,高亮当前标签所在的模块,但是有问题,后期再说,不需要的可以删掉
if (e) {
_this.events.pickPosition.x = e.clientX / renderer.domElement.clientWidth * 2 - 1;
_this.events.pickPosition.y = -(e.clientY / renderer.domElement.clientHeight * 2) + 1;
// 点击区域高亮显示
_this.pickEvents('show', _this.events.pickPosition, scene, camera, obj => {
// obj.material.emissive.setHex(0xEA3639)
// obj.userData.checked = !obj.userData.checked;
// if (!obj.userData.checked) {
// // 恢复默认颜色
// obj.material.emissive.setHex(_this.events.pickedObjectSavedColor)
// } else {
// // 将其发射颜色设置为闪烁的红色/黄色
// obj.material.emissive.setHex(0xFF3443)
// }
})
}
});
tween.easing(TWEEN.Easing.Quadratic.InOut);
tween.start();
},
重点:需要在动画中加入这么一行,才能开启过渡效果