incorrect event.clientY value with ThreeJs raycaster when header bar displayed

406 views Asked by At

Here is the problem :

I would like to paste a sphere on a 3D model when I click on it. I use ThreeJs raycaster to do that. It works perfectly if canvas covers the whole page, but not if I add a header bar to the page. Here are some graphic examples :

Without header bar, the sphere appears under mouse pointer, no problem: a Ok

Now with header bar; oops, the sphere is more downward than mouse pointer: a Ko

If I scroll down the page the problem occurs too, even if there's no header bar.

Here is the js code :

function addSphere(coords, color) {

    sphere = new T.Mesh(sphereGeometry, sphereMaterial)

    sphere.position.set(coords.x, coords.y, coords.z)

    sphere.name = 'Sphere'

    scene.add(sphere)

}


function listeners() {

    document.addEventListener('resize', function() {

        var width = window.innerWidth
        var height = window.innerHeight

        camera.aspect = width / height
        camera.updateProjectionMatrix()
        renderer.setSize(width, height)

    }, false)


    container.addEventListener('click', function(e) {

        console.log('Clic sur container')

        e.preventDefault()

        mouse.x = (e.clientX / width) * 2 - 1
        mouse.y = - (e.clientY / height) * 2 + 1

        ray.setFromCamera(mouse, camera)

        var intersects = ray.intersectObjects(scene.children)

        if ( intersects[0].object.name == 'Mannequin' ) {

            // var coords = mannequin.worldToLocal(intersects[0].point)
            var coords = intersects[0].point

            addSphere(coords, 'color')

            console.log('Clic sur le mannequin')
            console.log(intersects[0])

        }

        if ( intersects[0].object.name == 'Sphere' ) {

            console.log('Clique sur la sphère : ', intersects[0].object)

        }

    }, false)

}

And index.html:

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

    <title>Title</title>

    <link rel="stylesheet" href="css/style.css">

    <!-- <script src="js/app.js"></script> -->
    <!-- <script src="js/exemple.js"></script> -->

</head>
<body>

    <div id="header-bar" style="left: 0; right: 0; top: 0; height: 44px; line-height: 44px; text-align: center; font-size: 1.4em">Header bar</div>

    <div id="container"></div>

    <div id="buttons" style="display: block; left: 0; right: 0; bottom: 0; height: 25px;">

        <button id="btnFront">Front</button>
        <button id="btnBack">Back</button>
        <button id="btnRight">Right</button>
        <button id="btnIso1">Iso 1</button>
        <button id="btnIso2">iso 2</button>
        <button id="btnFeet">Feet</button>
        <button id="btnDelete">Delete</button>
        <button id="btnUndo">Undo</button>
        <button id="btnRotation">Rotation on/off</button>

    </div>

    <!-- Three.js -->
    <script src="lib/threejs/three.js"></script>
    <script src="lib/threejs/OrbitControls.js"></script>
    <!-- <script src="lib/threejs/CanvasRenderer.js"></script>
    <script src="lib/threejs/Projector.js"></script> -->

    <script src="js/mannequin.js"></script>
    <script src="js/events.js"></script>

</body>
</html>

I don't understand what happens. Anyone has an idea ?

Thank you by advance.

2

There are 2 answers

0
Djé Rèm On

@prisoner849 Thank you for your answer. it led me to these links :

http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates

&

Real mouse position in canvas

I tried:

function getMousePositionInCanvas(canvas, e) {

    var rect = canvas.getBoundingClientRect()
    return {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top
    }

}


    var mousePosInCanvas = getMousePositionInCanvas(document.querySelector('canvas'), e)

    mouse.x = (mousePosInCanvas.x / width) * 2 - 1
    mouse.y = - (mousePosInCanvas.y / height) * 2 + 1

And it works perfectly.

Thank you very much !

1
Djé Rèm On

I solved the problem by removing 44 units from e.clientY (44 is the height of the header bar).

mouse.x = (e.clientX / width) * 2 - 1
mouse.y = - ((e.clientY - 44) / height) * 2 + 1

But if I scroll the page the problem persists.