中秋节到了,吃月饼必不可少,为了让大家能够更愉快的过中秋,我花了一晚的功夫开发了一个摇一摇的页面,通过页面摇一摇,可以摇出各种各样的月饼,快来试试你的本命月饼是什么吧。
注意玩耍时如果摇不出可尝试加大摇一摇幅度哦。不过请小心练出麒麟臂 💪,并在无人环境下进行,避免被误以为发病(🐶)。
注意一共收集了 25 种月饼,越少见的月饼越难摇出,看看你能收集到哪些月饼吧。
技术实现
下面稍微讲一下技术实现的内容。
摇一摇
首先是关于摇一摇部分,摇一摇的实现主要使用的是浏览器中的 devicemotion
事件,该事件可以获取到设备的速度变化、位置、方向等信息。
window.addEventListener('devicemotion', e => { const devicemotion = { accelerationIncludingGravityX: e.accelerationIncludingGravity.x!, accelerationIncludingGravityY: e.accelerationIncludingGravity.y!, accelerationIncludingGravityZ: e.accelerationIncludingGravity.z! }; if (latestDevicemotion) { // 摇一摇的幅度 const thresholdCount = Math.max( Math.abs(latestDevicemotion.accelerationIncludingGravityX - devicemotion.accelerationIncludingGravityX), Math.abs(latestDevicemotion.accelerationIncludingGravityY - devicemotion.accelerationIncludingGravityY), Math.abs(latestDevicemotion.accelerationIncludingGravityZ - devicemotion.accelerationIncludingGravityZ) ); // 大于一定幅度才计算 if (thresholdCount > 20) { shakeCount += 8; } shakeCount = Math.max(0, shakeCount - 2); } latestDevicemotion = devicemotion; }); 复制代码
代码如上,通过 devicemotion
事件数据,可以获取到三个方向的加速度,然后将其和之前的数值进行比对即可得出摇一摇的幅度,然后通过 shakeCount
来模拟记录持续摇一摇的时长,从而实现模拟摇一摇触发的效果。
需要注意的是,在安卓设备中,需要在 https
环境下才能正常触发 devicemotion
事件,所以本地开发时会有些麻烦,必须对本地开发工具启用 https
。而在 iOS
中,除了必须是在 https
环境外,还需要使用 DeviceMotionEvent.requestPermission
获取到权限后才能监听到事件,所以我将事件绑定抽取出来,根据环境来进行调用,具体相关代码如下:
if (typeof (DeviceMotionEvent as any).requestPermission === 'function') { (DeviceMotionEvent as any) .requestPermission() .then((permissionState: string) => { if (permissionState === 'granted') { bindEvent(); } }) .catch(() => { alert('获取权限失败'); }); } else { bindEvent(); } 复制代码
震动与音效
当摇动幅度和摇动时间达到一定阈值后,摇一摇事件触发,会从月饼列表中抽取随机抽取一个月饼,并且会调用手机震动和播放音效来提醒摇一摇的用户出货了。🐶
if (thresholdCount > 80 && shakeCount > 100) { window.navigator.vibrate?.(200); const audio = document.createElement('audio'); audio.src = '/success.mp3'; document.body.appendChild(audio); audio.onended = () => document.body.removeChild(audio); audio.play(); } 复制代码
不过实际月饼抽取逻辑略有些出入,并不是摇一摇后触发,而是预先选定,有兴趣的可以看下源码。
需要注意的是,无论是震动、还是播放音效,在 iOS
中由于兼容问题和系统限制,均无法实现。🤦♂️ 真不是我的锅。所以各位 iOS
用户在玩耍时还得看好手机,出货了就停止,不然。。。手臂真的会很累的。
总结
本文主要是就着中秋节这个档口,正好试试浏览器的 devicemotion
事件的使用,实际过程中坑还是挺多的,因为浏览器不触发事件也没有报错,都不知道 https
和 iOS
中申请权限的问题,导致浪费了一些时间去查资料。
不过该事件还是很有趣,有创意可以玩出很多花样,依稀记得很久以前 Google
有个绝地武士将手机当光剑的游戏来着。