Receiving transformed mouse event data from DOM objects with a CSS 3D transform
Asked Answered
B

1

7

Is there currently any data in a javascript mouse event that would allow me to easily find or calculate a mouse position relative to the 3D space of a transformed element?

To illustrate visually,
At left is the div without a 3d matrix, at right is the div after 3d transformation.
o is the origin of the mouse event

                +
               /|
              / |
+-----+      +  |
|     |      |  |
|    o|  =>  | o|
|     |      |  |
+-----+      +  |
              \ |
               \|
                +

In the script below, clicking the same pixels in the div will report an event.layerX which is in the 2d transformation space of the document/screen.

I'm aware, but not thrilled about the prospect of parsing the div's matrix3d and using that to multiply to the event position to discover this, however in the real implementation, the divs will have more complex transformations and this would need to be done on every frame for more than one object and I worry about the overhead that would bring...I certainly wouldn't mind help with that if it's my only option though.

<!doctype html>  

<html lang="en">

<head>
    <meta charset='utf-8'>
    <title></title>
    <style type="text/css" media="screen">

        body {
            background-color: #FFF;
        }

        img {
            position: absolute;
        }

        #main {
            margin: 0;
            -webkit-perspective: 1800;
        }

        #card {
            position: relative;
            margin: 0 auto;
            width: 420px;
            height: 562px;
            -webkit-transform-style: preserve-3d;
            -webkit-transform-origin: center center;
        }

        #card .page {
            position: absolute;
            -webkit-transform-style: preserve-3d;
            -webkit-transform-origin: left center;
        }

        #card .page .face {
            position: absolute;
            width: 100%;
            height: 100%;
            -webkit-transform-style: flat;
        }
        #card .page .face.front {
            z-index: 1;
            -webkit-backface-visibility: hidden;
        }
        #card .page .face.back {
            -webkit-transform: rotateY(180deg) translateX(-420px);
        }

    </style>
</head>

<body>
    <div id='main'>
        <div id='card'>
            <div class='page draggable'>
                <div class='face front'>
                    <img src='front.jpg'/>
                </div>
                <div class='face back'>
                    <img src='back.jpg'/>
                </div>
            </div>
        </div>
    </div>

    <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js'></script>
    <script>


        function rotate() {
            $('.page').css("-webkit-transform", "rotate3d(0, -1, 0, 60deg)");
            $('.page').mousedown(function(event) {
                console.log(event.layerX);
            });
        }

        $(document).ready(function() {
            rotate();
        });

    </script>

</body>

</html>
Beghtol answered 8/3, 2011 at 1:13 Comment(0)
M
0

It seems like you are looking for the offsetX property event. Maybe you'd have to create listeners to every .face in order to identify the events, because the offsetX is calculated based on the target that fires the event. Or maybe you want the coordinates to start from 0 on the left to width*2 on the right, then you could use the layerX and the original width of your elements:

console.log((event.layerX<0?width-event.offsetX:width+event.offsetX));

Using the offsetX/offsetY works no matter what transform you use (at least in the many scenarios I've tested)

Migratory answered 24/5, 2011 at 5:7 Comment(2)
offsetX and offsetY are definitely a viable solution. Seems like your layer example would work for a rotation along one axis, but would break down with any more. Slapped some listeners on the front and back face, and oddly, a face with -webkit-backface-visibility set to hidden doesn't register mousedowns.Beghtol
Any idea how to get the same offsetX quantity, pre-transformation, for touch events? It doesn't appear to exist there.Cowper

© 2022 - 2024 — McMap. All rights reserved.