我需要使用
React.JS
检测用户是否以及如何移动手机(我正在使用 Next.JS 14.0.4)。为此,我开始寻找一些可以用陀螺仪或加速度计检测它的库,并达到了Shake.js、运动传感器和默认的JS事件devicemotion
对于每个图书馆或活动,我都根据相应网站上提供的示例编写了代码。
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>
);
}
然后我用
"devip": "next dev -H 0.0.0.0 -p 8080"
启动主机(我插入我的 IP,而不是 0.0.0.0),然后从桌面浏览器和手机连接到主机(尝试了 Safari 和 Chrome)。
无论我如何摇动手机,都没有任何反应。我尝试手动更改每个块中的 setState,例如:
setShakeDetected(true);
在每个事件侦听器内,它不会改变此状态
Shake.js
已于2020年存档,因此似乎没有得到积极维护。
话虽如此,
Shake.js
依赖于 devicemotion
,因此这适用于您的 Shake.js
和 devicemotion
方法。
devicemotion
MDN 文档:
此功能仅在安全上下文 (HTTPS)、部分或所有支持的浏览器中可用。
默认情况下,vite 在
http
下运行项目。如果这是您的情况,则不会因此触发事件。
要在
https
中运行您的项目,您必须更改您的 vite.config.js
文件。在 https
中运行项目的一个简单方法是通过 @vitejs/plugin-basic-ssl 插件。
您可以通过以下方式安装:
npm i @vitejs/plugin-basic-ssl
然后将其添加到vite.config.ts
中的插件列表中:
import basicSsl from '@vitejs/plugin-basic-ssl'
export default {
plugins: [
basicSsl()
]
}
之后您的代码应该可以正常工作。请注意,此插件对于开发目的很方便。对于生产,您应该生成自己的证书。