vue项目实现摇一摇h5

一、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轴方向上旋转的速率的对象。旋转速率的单位为度每秒

  1. alpha: 设备沿着垂直屏幕的轴的旋转速率
  2. beta: 设备沿着屏幕左至右方向的轴的旋转速率
  3. 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>

 图片文件:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值