Detect Google Cardboard Magnetic Button Click in Javascript
Asked Answered
P

3

4

With refering to Detecting Magnetic Button on Cardboard in C# is there anyway to access the magnetic cardboard button within Javascript in a browser of a mobile phone?

cheers Stefan

Penniepenniless answered 26/10, 2016 at 19:9 Comment(0)
P
3

I was finally able to solve the problem myself. Fortunately time and a bit of luck helped for solution (it wouldn't have been possible by the time I was actually asking for it).

The solution is based on the "Generic Sensor API" proposed by the W3C and in particular the implementation for the Magnetometer API.

see the following specs - https://developers.google.com/web/updates/2017/09/sensors-for-the-web - https://www.w3.org/TR/generic-sensor/ - https://w3c.github.io/magnetometer/

However, there are some caveats:

  • You need to have at least Chrome version 63 (and I am not aware that any other browser currently supports it) which by the time of my writing is only available as a developer edition.

  • You need to enable

    • chrome://flags/#enable-generic-sensor

    • chrome://flags/#enable-generic-sensor-extra-classes

  • Code must be delivered via HTTPs or from localhost! If not, you get Security exceptions...

I have extracted the following code from my much more complex code. I hope I did not overlook anything.

this.lastSensorX = 0;

try {
  this.sensor = new Magnetometer();
  if (this.sensor!==undefined) {
       this.sensor.start();
  }
} catch(err) {
            console.log("Magnetometer not supported. Make sure you configure chrome://flags/#enable-generic-sensor-extra-classes and deliver via HTTPS.");
}

....

// Check major differences on Magnetometer and identify this as a button-click

if (this.sensor !== undefined) {
  this.sensor.onreading = () => {
     var delta= this.sensor.x-this.lastSensorX;
      
     if (delta > 100 ) {
           // do whatever you want to do, in case the cardboard magnet has been "clicked"
     }
     this.lastSensorX = this.sensor.x;
  }
  
  this.sensor.onerror = event => console.log(event.error.name + " (Magnetometer): ", event.error.message);

}

I used the above snipped in my own application it it works perfectly.

Penniepenniless answered 31/10, 2017 at 19:52 Comment(0)
A
0

You can actually just listen for a touchstart event on the canvas that is rendering your WebGL scene.

canvas.addEventListener( "touchstart", onCardboardClick );

function onCardboardClick() {}

Click is technically happening on a mouseup so you might want to attache the touchend event instead. That is up to you.

EDIT FOR COMMENT

Make sure that the event listener gets added to the right canvas. You mentioned you used THREE.js. So I assume you have an instance of WebGLRenderer. You can make sure you get the right element by taking the reference there. After everything is setup you can add

renderer.domElement.addEventListener( "touchstart", onCardboardTouch );
Aeneous answered 1/12, 2016 at 19:14 Comment(12)
Hi Mathias, Your answer looked very promising. # Unfortunately it has no effect. The HTML that contains the drawing which is done with THREE.js is as follows ` <div id="maze"> <canvas ..> </div> class MazeTemplate { start() { ... this.canvas = document.getElementById('maze').getElementsByTagName("canvas")[0]; this.canvas.addEventListener( "touchstart", MazeTemplate.onCardboardClick ); ... } static onCardboardClick() { // do something } } ` Unfortunately clicking the button does nothing. Do you have any further hint?Hartford
@StefanHöhn I edited my answer. It was too long for the comments and as you know it's hard to get the formatting right :)Aeneous
Sorry, I have overlooked your change of the post and only by chance saw it 2 days ago. I tried that out and it now triggers the event. However, the event is not triggered on the Magnet Button but when I touch the phone screen. So the "touchstart" event is unfornately not the one I need. But still thanks for your effort!Hartford
@StefanHöhn not a problem. Unfortunately there is not separate event for when cardboard touches the screen. The Cardboard button is meant to work like a finger touching the screen. So if your solution works when you touch the screen at any point, so should the cardboard button. Can you make sure that the cardboard button actually touches the screen. If you've used the Cardboard for a while, this might wear out. (Maybe test it with a different app)Aeneous
Okay, now I know where the misunderstanding comes from. The cardboard button does not touch the screen but is a magnet button that influences some magnet sensor (magnetometer) within the phone. See hereHartford
You are right. I assumed it would listen to the screen touch, since there is no magnetometer API for the web this thus far. But I was wrong. Sorry about this!! :(Aeneous
I finally found a solution, @Mathias. Have a look below.Hartford
@StefanHöhn This is awesome. I was not aware of this API at all. Definitely learned something new today. You should probably accept your answer as the correct one.Aeneous
Ok, I marked it as "answer". If you like you can upvote it then :-)Hartford
This code don't work if I entering in VR-mode why? In normal mode it work!Barrie
Just for everyone out there to know who lands here googling, touch events are disable are disabled in webvr to prevent accidental screen touches from activating as you put the phone in the viewer. Also, probably because daydream used screen touches for phone orientation or something... So far I can't get any touch-based input to fire, wish I had an answer for you, but I've been trying everything and getting nothing.Cinerator
Note: I finally found a way, see answer here: https://mcmap.net/q/1625879/-detect-google-cardboard-magnetic-button-click-in-javascriptCinerator
C
0

I don't have nor am I concerned with magnetic buttons in 2020, but I struggled mightily to find any way to implement the V2 cardboard button in web VR.

Touch events are disabled in cardboard, and while I see references to gamepad events and a mono-button gamepad being injected to cover touch events in chrome, no gamepad has shown up for me that I've seen.

I finally found a library that seems to cover all the bases--it listens for anything, and fires everything as a single button, and something is firing--so I'm going back over all the places I researched and found non-working answers and linking it to help the next poor soul:

https://dougreeder.github.io/aframe-button-controls/example.html

Cinerator answered 28/6, 2020 at 20:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.