使用threeJS引入模型进行点击事件,其实有一个是将获取到坐标位置进行webgl坐标系的转换
全屏状态下直接利用window.innerWidth和 window.innerHeight进行计算即可,代码如下
- // 校验控制器旋转的时候不触发点击事件
- boxClickEvent() {
- const self = this;
- let x, y;
- //获取鼠标按下的位置
- this.renderer.domElement.addEventListener('mousedown', function (event) {
- x = event.pageX;
- y = event.pageY;
- });
- // 鼠标释放
- this.renderer.domElement.addEventListener('mouseup', function (event) {
- const newX = event.pageX;
- const newY = event.pageY;
- if (x == newX && y == newY) {
- // 位置相同的操作
- self.onDocumentMouseDown(event);
- }
- });
- },
- //获取点击的事件
- onDocumentMouseDown(event) {
- const raycaster = new THREE.Raycaster();
- const mouse = new THREE.Vector2();
- //转换为webgl坐标系下的鼠标位置
- mouse.x = (event.clientX / window.innerWidth) * 2 - 1; // 全屏状态
- mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; // 全屏状态
- if (event.detail !== 2) { // 判断点击次数
- console.log('单击',event);
-
- } else {
- console.log('双击击',event);
- }
- },
非全屏状态,使用实际的canvas的getBoundingClientRect(),获取canvas的相关信息
打印下canvas.getBoundingClientRect()👇

可以看出包含canvas画布的尺寸和相对屏幕上下左右的距离等信息,可以直接进行计算了
关于renderer,我是这样声明的
const self = this;
// 创建渲染器对象
self.renderer = new THREE.WebGLRenderer({ antialias: true });
// 渲染区域尺寸
self.renderer.setSize(self.$refs.threeBox.clientWidth, self.$refs.threeBox.clientHeight);
// 页面中插入canvas对象
self.$refs.threeBox.appendCh
可以把 this.renderer.domElement 直接替换成自己实际声明的canvas
- onDocumentMouseDown(event) {
- const raycaster = new THREE.Raycaster();
- const mouse = new THREE.Vector2();
- // 转换为webgl坐标系下的鼠标位置
- mouse.x = ((event.clientX - this.renderer.domElement.getBoundingClientRect().left) / this.renderer.domElement.clientWidth) * 2 - 1;
- mouse.y = -((event.clientY - this.renderer.domElement.getBoundingClientRect().top) / this.renderer.domElement.clientHeight) * 2 + 1;
- // 从相机发射一条经过鼠标点击位置的射线
- raycaster.setFromCamera(mouse, this.camera);
- // 计算射线和模型的交点
- const intersects = raycaster.intersectObjects(this.scene.children, true);
- // ...
- }