一开始看到这个需求简直是头大,根本无从下手,观察竞品发现是定位到页面上的,首先这个方向实现是对的,但在后面实现剪切截图下载时发现可能还是有点出入。
定位在右上角是一个立方体,分别对应的是模型的前后左右上下六个面,单独实现并将模型和立方体布局是没有问题的。难点就是互相转动的时候要一起转动,且角度、倾斜角,旋转角度一致!!
跟交接的同事谈到这部分的时候,他的角度出发点是2维面和3维面的坐标转换,当时就感慨有点牛逼,也加重了开发心理难度。但是在熟读three.js文档后发现OrbitControls
辅助设置相机参数,这个属性,旋转中心设置曾经用到过他。
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
// 浏览器控制台查看相机位置变化
console.log('camera.position',camera.position);
});
他还有一个change事件,交接同事的思路是拿到旋转的坐标通过组件传值,子组件到父组件通过emit传值触发对应事件,父组件到子组件是通过ref拿到子组件暴露出去的set坐标的方法来父子互动。
立方体和模型分别都具备 OrbitControls 属性,都具备调用change事件,在change事件中就可以拿到各自水平旋转的弧度值,上下旋转的弧度值,将这两个值互相通知经过公式的转化就是各自相机角度需要转动的坐标值。
function getSpin(data) {
const { phi, theta } = data
// 计算与边界框最远点的距离
const distance = size.length() * 2;
camera.position.x = modelCenter.x + distance * Math.sin(phi) * Math.cos(theta);
camera.position.y = modelCenter.y + distance * Math.cos(phi);
camera.position.z = modelCenter.z + distance * Math.sin(phi) * Math.sin(theta);
camera.lookAt(initialCameraTarget); // 相机朝向旋转中心点
}