# 利用HTML5的devicemotion事件实现手机摇一摇抽奖，年会抽奖

2017-01-14 19:49:30来源:cnblogs.com作者:熊仔其人人点击

`if (window.DeviceMotionEvent) {    window.addEventListener('devicemotion', handler, !1);    lastTime = new Date();} else {    alert('你的浏览器不支持摇一摇功能.');}`

devicemotion事件对象中有一个accelerationIncludingGravity属性，该属性包括：一个包含x、y 和z 属性的对象，在考虑z 轴自然重力加速度的情况下，告诉你在每个方向上的加速度。该API的具体使用大家可以参考网上的资料，非常多，这里就不重复了。 摇一摇的具体逻辑如下：

`function handler(e) {    var current = e.accelerationIncludingGravity;    var currentTime;    var timeDifference;    var deltaX = 0;    var deltaY = 0;    var deltaZ = 0;    //记录上一次设备在x,y,z方向上的加速度     if ((lastX === null) && (lastY === null) && (lastZ === null)) {        lastX = current.x;        lastY = current.y;        lastZ = current.z;        return;    }    //得到两次移动各个方向上的加速度绝对差距    deltaX = Math.abs(lastX - current.x);    deltaY = Math.abs(lastY - current.y);    deltaZ = Math.abs(lastZ - current.z);    //当差距大于设定的阀值并且时间间隔大于指定阀值时，触发摇一摇逻辑    if (((deltaX > threshold) && (deltaY > threshold)) || ((deltaX > threshold) && (deltaZ > threshold)) || ((deltaY > threshold) && (deltaZ > threshold))) {        currentTime = new Date;        timeDifference = currentTime.getTime() - lastTime.getTime();        //时间间隔        if (timeDifference > timeout) {            //触发摇一摇事件            dealShake();            lastTime = new Date;        }    }    lastX = current.x;    lastY = current.y;    lastZ = current.z;}`

` 1 <!DOCTYPE html> 2 <html> 3 <head> 4     <meta charset="UTF-8"> 5     <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> 6     <title>摇一摇抽奖</title> 7    <style type="text/css"> 8        html,body{ width:100%; height:100%; background-color: #000; margin:0; overflow: hidden;} 9        .tip{ position: absolute; bottom: 30px; left: 10px; color: #fff; font-family: '楷体'; text-align: center; right: 10px; height: 32px; line-height: 32px; background-color: rgba(255,255,255,.4); border-radius: 3px; } .tip.active{ -webkit-animation: jump 1.5s linear; animation: jump 1s linear; } 10    </style>11 </head>12 <body>13     <div class="tip" id="tip"> </div>14     15     <script type="text/javascript">16         var lastX = null,17             lastY = null,18             lastZ = null;19         var threshold = 3; //灵敏度（值越小灵敏度越高）20         var timeout = 1000;21         var lastTime = null;22         var isShaking = !1;23         document.addEventListener('DOMContentLoaded', function (e) {24             ready();25         }, !1);26 27         /*脚本逻辑：28         *移动端JS脚本逻辑的实现，摇一摇的实现需借助html5新增的devicemotion事件，获取设备在位置和方向上的改变速度的相关信息。29         *devicemotion事件对象中有一个accelerationIncludingGravity属性，该属性包括：一个包含x、y 和z 属性的对象，在考虑z 轴自然重力加速度的情况下，告诉你在每个方向上的加速度。30         */31         function ready() {32             if (window.DeviceMotionEvent) {33                 window.addEventListener('devicemotion', handler, !1);34                 lastTime = new Date();35             } else {36                 alert('你的浏览器不支持摇一摇功能.');37             }38         }39 40         function handler(e) {41             var current = e.accelerationIncludingGravity;42             var currentTime;43             var timeDifference;44             var deltaX = 0;45             var deltaY = 0;46             var deltaZ = 0;47 48             //记录上一次设备在x,y,z方向上的加速度 49             if ((lastX === null) && (lastY === null) && (lastZ === null)) {50                 lastX = current.x;51                 lastY = current.y;52                 lastZ = current.z;53                 return;54             }55 56             //得到两次移动各个方向上的加速度绝对差距57             deltaX = Math.abs(lastX - current.x);58             deltaY = Math.abs(lastY - current.y);59             deltaZ = Math.abs(lastZ - current.z);60             //当差距大于设定的阀值并且时间间隔大于指定阀值时，触发摇一摇逻辑61             if (((deltaX > threshold) && (deltaY > threshold)) || ((deltaX > threshold) && (deltaZ > threshold)) || ((deltaY > threshold) && (deltaZ > threshold))) {62                 currentTime = new Date;63                 timeDifference = currentTime.getTime() - lastTime.getTime();64                 //时间间隔65                 if (timeDifference > timeout) {66                     //触发摇一摇事件67                     dealShake();68                     lastTime = new Date;69                 }70             }71 72             lastX = current.x;73             lastY = current.y;74             lastZ = current.z;75         }76 77         function dealShake() {78             if (isShaking) return;79             isShaking = !0;80 81             document.getElementById("tip").innerHTML = "恭喜您，摇中：" + GetName();82 83             setTimeout(function () {84                 isShaking = !1;85                 document.getElementById("tip").innerHTML = " ";86             }, 1000);87 88         }89 90         function GetName() {91             var chars = ["一等奖", "二等奖", "三等奖", "四等奖", "五等奖"];92             return chars[GetRandom(0, chars.length - 1)];93         }94         function GetRandom(minValue, maxValue) {95             return Math.round(Math.random() * (maxValue - minValue)) + minValue;96         }97     </script>98 99 </body>`
shake.html