- 6.4k
- 3
- 23
- 43
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