一、devicemotion事件
window 对象中devicemotion事件,它封装了运动传感器数据的事件,可以用来监听设备的加速度变化等信息。devicemotion事件对象有acceleration、accelerationIncludingGravity、rotationRate和interval四个属性
window.addEventListener("devicemotion", (e) => {
console.log(e)
});
注意:本地测试无法打印出来的时候请注意啦,devicemotion事件要在线上并且的https协议的域名才有效
acceleration(速度)和accelerationIncludingGravity(重力加速度)这两者的属性都包含三个轴:X轴、Y轴、Z轴,区别是阿acceleration是监听手机目前的移动速度,accelerationIncludingGravity监听的是手机的重力反应
rotationRate(旋转速度)
提供了设备在 alpha,beta, gamma轴方向上旋转的速率的对象。旋转速率的单位为度每秒
- alpha: 设备沿着垂直屏幕的轴的旋转速率
- beta: 设备沿着屏幕左至右方向的轴的旋转速率
- gamma: 设备沿着屏幕下至上方向的轴的旋转速率
interval(时间间隔)
表示从设备获取数据的间隔时间,单位是毫秒
二、苹果机ios13.3以上的机子不能直接监听devicemotion事件,需要用户手动同意开启权限才可以
IOS 13 之后新增的一个方法用来获取用户权限,获取到用户权限之后,我们就可以来检测加速度了,但是注意该方法是 IOS 13 之后才有的,在 IOS 13 之前这么写的话,DeviceMotionEvent下并没有requestPermission方法就会报错
判断苹果13的方法
var system = navigator.userAgent.toLowerCase();
if (system.indexOf("like mac os x") > 0) {
// 苹果机
var reg = /os [\d._]*/gi;
var info = system.match(reg);
var version = (info + "")
.replace(/[^0-9|_.]/gi, "")
.replace(/_/gi, ".");
var list = version.split(".");
// 苹果13手机 list[0] 16 list[1] 0
// 对苹果13以后的版本处理
if (list[0] > 15) {
if (
typeof DeviceMotionEvent !== "undefined" &&
typeof DeviceMotionEvent.requestPermission === "function"
) {
//要授权了哦
}
} else {
if (window.DeviceMotionEvent) {
//监听设备运动
window.addEventListener("devicemotion", (e) => {
console.log(e)
});
}
}
}
授权方法:
window.DeviceOrientationEvent.requestPermission().then((state) => {
if (state === "granted") {
// 监听传感器运动事件
if (window.DeviceMotionEvent) {
window.addEventListener("devicemotion", (e) => {
console.log(e)
});
} else {
alert("手机不支持陀螺仪功能哦");
}
} else if (state === "denied") {
alert("拒绝授权");
} else if (state === "prompt") {
alert("你对手机做了啥");
}
});
完整代码:
<template>
<div class="yao-box">
<div class="img">
<img id="yaoyiyao" src="../assets/shou.png" alt />
<div class="tip" v-if="isAuth">晃动你的屏幕开始摇一摇吧</div>
</div>
<div class="cover-box" v-if="!isAuth">
<div class="btn" @click="getAuth">获取一下你的权限哦</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
num: 10000, //抽奖次数
SHAKE_THRESHOLD: 8000, //动摇阀值,越高需要摇摆的幅度越大
loading: false, //防止摇摆过程中造成的误操作
last_update: 0, // 记录最后一次摇一摇的时间
x: 0,
y: 0,
z: 0,
last_x: 0,
last_y: 0,
last_z: 0,
isAuth: true, // 已经授权
};
},
mounted() {
this.init();
},
//页面销毁时
beforeDestroy() {
window.removeEventListener("devicemotion", this.devicemotion, false);
},
methods: {
init() {
var system = navigator.userAgent.toLowerCase();
if (system.indexOf("like mac os x") > 0) {
// 苹果机
var reg = /os [\d._]*/gi;
var info = system.match(reg);
var version = (info + "")
.replace(/[^0-9|_.]/gi, "")
.replace(/_/gi, ".");
var list = version.split(".");
// 苹果13手机 list[0] 16 list[1] 0
// 对苹果13以后的版本处理
if (list[0] > 15) {
if (
typeof DeviceMotionEvent !== "undefined" &&
typeof DeviceMotionEvent.requestPermission === "function"
) {
this.isAuth = false;
}
} else {
if (window.DeviceMotionEvent) {
//监听设备运动
window.addEventListener("devicemotion", this.devicemotion, false);
}
}
} else {
//判断设否授权了 设备运动权限
if (window.DeviceMotionEvent) {
//监听设备运动
window.addEventListener("devicemotion", this.devicemotion, false);
}
}
},
// 设备运动 方法
devicemotion(event) {
//获取加速度信息
//通过监听上一步获取到的x, y, z 值在一定时间范围内的变化率,进行设备是否有进行晃动的判断。
var acceleration = event.accelerationIncludingGravity;
var curTime = new Date().getTime();
// 最低间隔一秒
if (curTime - this.last_update > 1000) {
var diffTime = curTime - this.last_update;
this.last_update = curTime;
this.x = acceleration.x;
this.y = acceleration.y;
this.z = acceleration.z;
var speed =
(Math.abs(
this.x + this.y + this.z - this.last_x - this.last_y - this.last_z
) /
diffTime) *
10000;
//而为了防止正常移动的误判,需要给该变化率设置一个合适的临界值。
if (speed > this.SHAKE_THRESHOLD) {
if (this.num <= 0 && !this.loading) {
alert("抽奖次数用完了");
} else {
if (!this.loading) {
var block = document.getElementById("yaoyiyao");
block.classList.add("play");
setTimeout(() => {
alert("你中奖啦!"); // Do something
block.classList.remove("play");
this.loading = false;
}, 1500);
this.num -= 1;
this.loading = true;
}
}
}
this.last_x = this.x;
this.last_y = this.y;
this.last_z = this.z;
} else {
this.$toast.fail("不要太频繁哦");
// this.$message({title})
}
},
getAuth() {
let that = this;
window.DeviceOrientationEvent.requestPermission().then((state) => {
if (state === "granted") {
// 监听传感器运动事件
if (window.DeviceMotionEvent) {
that.isAuth = true;
window.addEventListener("devicemotion", this.devicemotion);
} else {
alert("手机不支持陀螺仪功能哦");
}
} else if (state === "denied") {
alert("拒绝授权");
} else if (state === "prompt") {
alert("你对手机做了啥");
}
});
},
},
};
</script>
<style lang="less" scoped>
.yao-box {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.img {
height: 15rem;
text-align: center;
margin-top: 12rem;
img {
display: inline-block;
height: 100%;
}
}
.play {
animation: play 0.3s linear 4;
}
.tip {
font-size: 1.5rem;
text-align: center;
margin-top: 4rem;
}
@keyframes play {
25% {
transform: rotate(-40deg);
}
75% {
transform: rotate(40deg);
}
100% {
transform: rotate(0deg);
}
}
.cover-box {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
.btn {
width: 80%;
height: 4rem;
background: #06ae56;
line-height: 4rem;
text-align: center;
border-radius: 4rem;
margin: 50vh 10vw;
color: #fff;
font-size: 1.5rem;
}
}
</style>
图片文件: