Renderings:
1. Before clicking
2. After clicking
Explanation: The effect is that I save the viewing angle and coordinates when I label the model, read the coordinate data when I click on the label, and then rotate to the corresponding viewing angle.
1. Install TWEEN
npm install --save @tweenjs/tween.js
2. Introduce on the current page
import TWEEN from "@tweenjs/tween.js";
3. When adding annotations, save the camera angle of view and model coordinates when adding annotations (the logic of adding annotations is in my previous blog)
// 创建标签
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. Listen to the label click event,
// 监听标签盒子内的标签点击事件
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. Coordinate transition
// 模型角度变化函数
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();
},
Key point: You need to add such a line in the animation to enable the transition effect