Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Question

Notice removed Current answers are outdated by Community Bot
Bounty Ended with mgarcia's answer chosen by Community Bot
Deleted typescript tag as it does not apply and added devicemotion.
Link
mgarcia
  • 6.4k
  • 3
  • 23
  • 43
Notice added Current answers are outdated by Zach
Bounty Started worth 50 reputation by Zach
Source Link
Lvasche
  • 561
  • 1
  • 7
  • 17

Detect mobile device movements

Using: Next.JS 14.0.4; iPhone 14

I need to detect if and how user moves his phone using React.JS (I'm using Next.JS 14.0.4). For this purpose I began looking for some libraries that can detect it with gyroscope or accelerometer and reached Shake.js , Motion sensors , and default JS event devicemotion

For every library or event I wrote a code by the example provided on corresponding site.

Some code

Shake.js:

"use client"
import React, { useEffect, useState } from 'react';
import Shake from 'shake.js';
export default function Home() {
 const [shakeDetected, setShakeDetected] = useState(false);
 useEffect(() => {
 const shakeEvent = new Shake({ threshold: 15, timeout: 1000 });
 shakeEvent.start();
 window.addEventListener('shake', shakeHandler, false);
 return () => {
 shakeEvent.stop();
 window.removeEventListener('shake', shakeHandler, false);
 };
 }, []);
 const shakeHandler = () => {
 setShakeDetected(true);
 setTimeout(() => setShakeDetected(false), 5000); // Reset after 5 seconds
 };
 return (
 <div>
 <h1>Shake Detection</h1>
 {shakeDetected ? <p>Shake detected!</p> : <p>Shake your device...</p>}
 </div>
 );
}

Motion sensors:

"use client";
import { useEffect, useState } from "react";
import styles from "./page.module.css";
import { Accelerometer } from "motion-sensors-polyfill";
export default function Home() {
 const [accelerationCoords, setAccelerationCoords] = useState({
 x: 0,
 y: 0,
 z: 0,
 });
 useEffect(() => {
 const sensor = new Accelerometer();
 sensor.addEventListener("reading", () => {
 setAccelerationCoords({
 x: sensor.x,
 y: sensor.y,
 z: sensor.z,
 });
 });
 sensor.start();
 return () => {
 sensor.stop();
 };
 }, []);
 return <main className={styles.main}>
 <p>{accelerationCoords.x}</p>
 <p>{accelerationCoords.y}</p>
 <p>{accelerationCoords.z}</p>
 </main>;
}

devicemotion:

import React, { useEffect, useState } from 'react';
export default function Home() {
 const [motion, setMotion] = useState({ x: 0, y: 0, z: 0 });
 useEffect(() => {
 function handleDeviceMotion(event) {
 setMotion({
 x: event.accelerationIncludingGravity.x,
 y: event.accelerationIncludingGravity.y,
 z: event.accelerationIncludingGravity.z,
 });
 }
 window.addEventListener('devicemotion', handleDeviceMotion);
 return () => {
 window.removeEventListener('devicemotion', handleDeviceMotion);
 };
 }, []);
 return (
 <div>
 <h1>Device Motion</h1>
 <p>X: {motion.x}</p>
 <p>Y: {motion.y}</p>
 <p>Z: {motion.z}</p>
 </div>
 );
}

Then I started host with "devip": "next dev -H 0.0.0.0 -p 8080" (I insert my ip instead 0.0.0.0) and then connect to the host both from desktop browser and from phone (tried both Safari and Chrome).

Result

No matter how much I shake my phone completely nothing happens. I tried to change setState in each block manually like:

setShakeDetected(true);

inside each event listener and it does not change this state

lang-js

AltStyle によって変換されたページ (->オリジナル) /