用devicemotion事件监听手机摇晃触发抽奖,需检测三轴加速度突变,以连续2–3帧强度>15 m/s²判定有效晃动,避免误触;须调用requestpermission()获取权限后监听。

用 DeviceMotion 事件监听手机摇晃来触发随机抽奖,核心在于检测加速度突变(尤其是 x/y/z 方向的瞬时变化),过滤掉静止和缓慢移动干扰,再在合适时机执行抽奖逻辑。关键不是“一直晃”,而是识别一次有力度、短时长的晃动动作。
监听 deviceorientation 和 devicemotion 的区别
DeviceMotion 提供加速度(含重力)、旋转速率等原始传感器数据,适合检测物理晃动;DeviceOrientation 只提供设备朝向(alpha/beta/gamma),易受缓慢转动干扰,不适合摇晃判定。务必用 window.addEventListener('devicemotion', handler)。
判断“有效摇晃”的实用阈值策略
单纯看单轴加速度峰值容易误触(比如走路震动)。推荐组合判断:
- 计算三轴加速度变化量:用当前 accelerationIncludingGravity 减去上一帧值,取各轴绝对值
- 定义“晃动强度”为
Math.max(|Δx|, |Δy|, |Δz|) - 连续 2–3 帧强度 > 15 m/s²(iOS/Android 常用起点),且总持续时间
- 晃动后加入 800ms 冷却期,防止连续触发
防抖 + 状态管理避免重复抽奖
用户可能连续猛晃多次,但应只响应第一次。建议用状态变量控制流程:
- 设
let isShaking = false标记是否已进入晃动响应中 - 检测到有效晃动后立即将
isShaking = true,并启动 setTimeout 延迟抽奖(如 300ms 后执行) - 在延迟期间忽略新晃动;延迟结束后重置
isShaking = false - 可选:晃动时播放轻微震动(
navigator.vibrate(50))或 UI 动画反馈,增强交互感
简单抽奖逻辑与兼容性提醒
抽奖本身是纯业务逻辑,例如从数组中随机取一项:
const prizes = ['一等奖', '谢谢参与', '二等奖', '再来一次']; const winner = prizes[Math.floor(Math.random() * prizes.length)];
注意:iOS Safari 13+ 要求用户手势(如点击)后才能启用 motion 权限,首次使用需先触发一次用户交互(例如点“开始摇一摇”按钮),再调用 requestPermission(仅 iOS):
if (typeof DeviceMotionEvent.requestPermission === 'function') {
document.querySelector('#start-btn').addEventListener('click', () => {
DeviceMotionEvent.requestPermission()
.then(permission => {
if (permission === 'granted') window.addEventListener('devicemotion', handleShake);
});
});
}










