手机处于横向模式时,Raycaster不起作用

时间:2019-12-26 12:23:44

标签: javascript three.js

我可以在PC上选择对象。 但是我在手机上运行它,这是行不通的!

PC屏幕截图: enter image description here 手机屏幕截图: enter image description here

注意:我通过CSS将手机上的画布旋转了90度(我想是因为此操作,但我不知道为什么):

transform-origin: left top;
transform: rotate(90deg);
import * as THREE from 'three';

export class PickupManager {

    raycaster: THREE.Raycaster;

    camera: THREE.Camera;

    scene: THREE.Scene;

    canvas: HTMLCanvasElement;

    constructor(camera: THREE.Camera, scene: THREE.Scene, canvas: HTMLCanvasElement) {

        this.raycaster = new THREE.Raycaster();

        this.camera = camera;

        this.scene = scene;

        this.canvas = canvas;

        this.addEventListener();
    }

    pickedObject: THREE.Object3D | any;

     ljj1: THREE.Object3D = null;
     ljj2: THREE.Object3D = null;
     ljj3: THREE.Object3D = null;
     ljj4: THREE.Object3D = null;
     ljj5: THREE.Object3D = null;

    pick = (normalizedPosition: THREE.Vector2) => {

        this.ljj1 = this.ljj1 || this.scene.getObjectByName("LJJ1");
        this.ljj2 = this.ljj2 || this.scene.getObjectByName("LJJ2");
        this.ljj3 = this.ljj3 || this.scene.getObjectByName("LJJ3");
        this.ljj4 = this.ljj4 || this.scene.getObjectByName("LJJ4");
        this.ljj5 = this.ljj5 || this.scene.getObjectByName("64mmB016");

        // 通过摄像机和鼠标位置更新射线
        this.raycaster.setFromCamera(normalizedPosition, this.camera);

        // 计算物体和射线的焦点
        const objects = [this.ljj1, this.ljj2, this.ljj3,this.ljj4, this.ljj5];
        const intersectedObjects = this.raycaster.intersectObjects(objects,true);

        if (intersectedObjects.length > 0) {    
            this.pickedObject = intersectedObjects[0];

            const obj:THREE.Object3D = this.pickedObject.object;
            //output name of selected object
            console.log(obj.name );

        } else {

            console.log("Not found!")
        }
    }

    getCanvasRelativePosition = (event: MouseEvent | TouchEvent) => {

        const rect: DOMRect = this.canvas.getBoundingClientRect();

        const position: THREE.Vector2 = new THREE.Vector2();

        if (event instanceof MouseEvent) {

            position.x = event.clientX ;
            position.y = event.clientY;

        }

        else if (event instanceof TouchEvent) {

            const touch: Touch = event.changedTouches[0];

            position.x = touch.clientX - rect.left;
            position.y = touch.clientY - rect.top;

        }

        else {
            throw "Incorrect event, needs MouseEvent or TouchEvent";
        }

        return position;
    }

    getPickPoint = (event: MouseEvent | TouchEvent) => {

        const canvasPosition = this.getCanvasRelativePosition(event);

        const pickPoint:THREE.Vector2 = new THREE.Vector2();

        // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
        pickPoint.x = (canvasPosition.x / window.innerWidth ) *  2 - 1;
        pickPoint.y = (canvasPosition.y / window.innerHeight) * -2 + 1;

        return pickPoint;

    }

    addEventListener = () => {

        this.canvas.addEventListener('mousedown', this.onMouseDown, false);

        this.canvas.addEventListener('touchstart', this.onTouchStart, false);

    }

    onMouseDown = (event: MouseEvent) => {

        event.preventDefault();

        this.pick(this.getPickPoint(event));

    }

    onTouchStart = (event: TouchEvent) => {

        event.preventDefault();

        this.pick(this.getPickPoint(event));

    }

}

我想要获取ljj1ljj2ljj3ljj4ljj5对象,我可以在PC上获取它,但是我不能通过电话获取。

1 个答案:

答案 0 :(得分:0)

如果您使用CSS旋转画布,则计算鼠标/触摸坐标的方法将无效。

要处理CSS转换后的元素,您需要一些相对复杂的代码

对于鼠标坐标,您可以使用event.offsetXevent.offsetY

对于触摸坐标,您需要生成综合事件,并将事件位置传递回浏览器,以便它可以为您生成event.offsetXevent.offsetY

请参见How to get a canvas relative mouse position of a CSS 3D transformed canvas?

另请参见this examplethis gist