jeromeetienne / AR.js

Efficient Augmented Reality for the Web - 60fps on mobile!
MIT License
15.78k stars 2.22k forks source link

Touch Event on Mobile Executes One Event Behind #546

Closed taylordigital13 closed 5 years ago

taylordigital13 commented 5 years ago

Describe the bug This problem is specifically when making objects in the a-scene clickable. I have an event trigger when the object is touched using the raycaster, but I essentially need to touch the screen again to get it to execute the desired function. Also, the clicking is off on the object itself (doesn't line up exactly with the object in scene, though that's another issue). Events are executing behind by one touch. For instance, if the object is indeed intersected by the raycaster and it is considered a hit, the next touch input to the screen camera area will trigger the event, even if nothing is intersected by the raycast. What is interesting though, is if there is an event "on deck" and you click a button that is outside of the a-scene (like a gui button), it will reset the queue and you will need another two clicks (one on the object, one anywhere else) in order to get the event to fire again. What is also interesting is that this is only a problem with events on raycasted objects. This is not an issue with the gui button that is not included in the a-scene.

I have tried using various forms of input triggers for the event listener (click, mousedown, mouseup, touchstart, etc.) and all of them seem to either reproduce the issue or not work at all.

Note: I'm using the following versions: A-Frame: 0.6.1 Three: ^0.86.0 WebVR Polyfill: ^0.9.36 AR.js: 1.6.2

To Experience the issue I am referring to

https://www.techstuffandsuch.com/AR.js-master/aframe/VideoAndButton/newindex.html

I have it hosted it in the above link. You can go to it on mobile and test it on the marker image in the link below. The video is not clickable, but the image covering the image marker is clickable (you pretty much need to hit it in the middle for the raycast to recognize it as a hit).

https://techstuffandsuch.com/wp-content/uploads/2019/06/pattern-UnityLogoARjs-copy.png

Expected behavior Upon the first click, the event will execute.

Desktop (please complete the following information): Chrome Mobile (Android Pie)

Smartphone (please complete the following information): Pixel 3

taylordigital13 commented 5 years ago

The code looks like the following:

<!-- BEGIN: Top HTML -->
<!DOCTYPE html>
<!-- include aframe -->
<script src="../demos/vendor/aframe/build/aframe.min.js"></script>
<!-- include ar.js -->
<script src="../build/aframe-ar.js"></script>

<!-- to load .ply model -->
<script src="https://rawgit.com/donmccurdy/aframe-extras/v3.13.1/dist/aframe-extras.loaders.min.js"></script>

<!-- END: Top HTML -->
<!-- BEGIN: Unity Compiled Events -->
<script>
    AFRAME.registerComponent('button', {
        init: function () {
            var marker = document.querySelector("#marker");
            var button = document.querySelector("#mutebutton");
            var Video_0 = document.querySelector("#Video_Asset_0");
            var Plane_1 = document.querySelector("#Plane_1");
            marker.addEventListener("markerFound", function (evt) {
                Video_0.play();
            });
            marker.addEventListener("markerLost", function (evt) {
                Video_0.pause();
            });
            button.addEventListener("click", function (evt) {
                console.log("button clicked")
                if (Video_0.muted == true) {
                    button.innerHTML = "Mute";
                    Video_0.muted = false;
                } else {
                    button.innerHTML = "Unmute";
                    Video_0.muted = true;
                }
            });
            Plane_1.addEventListener("mousedown", function (evt) {
                open("https://www.google.com");
            });
        }
    });
</script>
<!-- END: Unity Compiled Events -->

<!-- BEGIN: Middle HTML -->

<body style='margin : 0px; overflow: hidden; font-family: Monospace;'>
    <div style='position: absolute; bottom: 10px; right: 30px; width:100%; text-align: center; z-index: 1;'>
        <button id="mutebutton" style='position: absolute; bottom: 10px'>
            Unmute
        </button>
    </div>
    <!-- <a-scene embedded arjs='debugUIEnabled: false; sourceType: video; sourceUrl:../../data/videos/headtracking.mp4;'> -->
    <a-scene embedded arjs='debugUIEnabled: false; sourceType: webcam'>
        <a-entity id="mouseCursor" cursor="rayOrigin: mouse"
            raycaster="objects: .intersectable; useWorldCoordinates: true;"></a-entity>
        <!-- END: Middle HTML -->

        <!-- BEGIN: Unity Compiled Assets -->
        <a-assets>
            <video id="Video_Asset_0" autoplay="false" loop crossorigin="anonymous" src="videos/Unity3D-Trailer.mp4"
                webkit-playsinline playsinline controls muted></video>
        </a-assets>
        <!-- END: Unity Compiled Assets -->
        <!-- BEGIN: Add Image Target (marker) -->
        <a-marker id="marker" type="pattern" preset="custom" src="pattern-UnityLogoARjs.patt"
            url="pattern-UnityLogoARjs.patt" emitevents="true" button>
            <!-- END: Add Image Target (marker) -->

            <!-- BEGIN: Unity Compiled Objects -->
            <a-video src="#Video_Asset_0" id="Video_0" class="intersectable" width="1" height="0.59016"
                position="0 0.301 -0.471" rotation="329.6259 0 0" color="#FFFFFF" transparent=False>
            </a-video>
            <a-plane src="textures/46607-otherunitylogo.png" id="Plane_1" class="intersectable" width="0.9535136"
                height="0.9535136" position="-0.003 0.009000001 0.082" rotation="270 0 0" color="#FFFFFF"
                transparent=True>
            </a-plane>
            <!-- END: Unity Compiled Objects -->

            <!-- BEGIN: Bottome HTML -->
        </a-marker>
        <a-entity camera></a-entity>
    </a-scene>
</body>

</html><!-- END: Bottome HTML -->
taylordigital13 commented 5 years ago

Wow, I've been struggling with this for days but as soon as I post about it online I figure it out lol. I switched to using A-Frame version 0.9.2 and it fixed it. Changed the code at the top from this:

<script src="../demos/vendor/aframe/build/aframe.min.js"></script>

to this:

<script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script>