模型点击事件网上教程挺多的,官网好像也有demo,这里我就只记录我碰到的问题以及解决方案:
首先要清楚一件事,就是模型的展示需要一个容器,当这个容器是body|window 和 非全屏的容器时,是有区别的,全屏的坐标拾取方法:
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
非全屏:
let getBoundingClientRect = container.getBoundingClientRect()
mouse.x = ((event.clientX - getBoundingClientRect .left) / container.offsetWidth) * 2 - 1;
mouse.y = -((event.clientY - getBoundingClientRect .top) / container.offsetHeight) * 2 + 1;
非全屏,且有存在缩放问题:【我这里用的一个框架, 会根据屏幕的比例和浏览器的缩放比例去自动适应。达到布局不变。容器位置看起来也不变】当存在缩放且不是全局容器时:
let div3DLeft = (window.innerWidth - renderer.domElement.clientWidth * zoom) / 2; // 由于容器位置看起来不变,所以直接用window来计算。
let div3DTop = window.innerHeight - renderer.domElement.clientHeight * zoom;
// 这里获取容器距离 window的 left 和top,
// renderer.domElement.clientWidth * zoom, 容器的实际大小会被缩放, 所以需要乘以 缩放比例zoom
mouse.x = ((event.clientX - div3DLeft) / (renderer.domElement.clientWidth * zoom)) * 2 -1;
mouse.y = -((event.clientY - div3DTop) /(renderer.domElement.clientHeight * zoom)) *2 +1;
添加CSS2DObject
分为三个步骤:
1:创建css2dobject 【const divLabel = new CSS2DObject(div);】
labelRenderer.setSize(dom.clientWidth, dom.clientHeight);【设置大小和属性】
labelRenderer.domElement.style.position = "absolute";
labelRenderer.domElement.style.top = "0px";
labelRenderer.domElement.style.outline = "none";
labelRenderer.domElement.style.zIndex = "-999";
2. 创建 渲染器 render 【labelRenderer = new CSS2DRenderer();】,添加到容器下:【dom.appendChild(labelRenderer.domElement);】
3.控制器:【controls = new OrbitControls(
camera,
labelRenderer.domElement
);】
4.渲染 【labelRenderer.render(scene, camera);】
5. 更新 【function animate() {
//更新控制器
render();
//更新性能插件
controls.update();
requestAnimationFrame(animate); //告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
}
】