2

I can select objects on PC. But i run it on phone, it's not work!

PC screenshots: enter image description here Phone screenshots: enter image description here

NOTE: I rotated the canvas 90 degrees on the phone by the CSS(I guess it's because of this operation, but I don't know why):

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));

    }

}

I want get the ljj1,ljj2,ljj3,ljj4,ljj5 object, i can get it on PC, but i can't get it on phone.

gman
  • 100,619
  • 31
  • 269
  • 393
Hong Li
  • 21
  • 1
  • Have you tested that rotation on your PC first? With the transform origin at the top-left, you might be rotating the element almost completely off the page. – Andrea Dec 26 '19 at 14:25
  • @Andrea I use the css: margin-left: 100%; move canvas , and exchange window size and canvas size by the code: canvas.style.width =`${window.innerHeight}`; canvas.style.height = `${window.innerWidth}`; so we can see the scene – Hong Li Dec 27 '19 at 02:33
  • this is online demo: https://wlczmsc.com/U3D/app.html – Hong Li Dec 27 '19 at 02:40

1 Answers1

0

If you rotated the canvas using CSS then the way you compute mouse/touch coordinates won't work.

For handing CSS transformed elements you need some relatively complicated code

For mouse coordinates you can use event.offsetX and event.offsetY

For touch coordinates you need to generate synthetic events that pass the event position back into the browser so that it will generate event.offsetX and event.offsetY for you.

See How to get a canvas relative mouse position of a CSS 3D transformed canvas?

Also see this example and this gist

gman
  • 100,619
  • 31
  • 269
  • 393