客户想要通过网页实现一个类似微信摇一摇的小游戏,周末在家没事,就做了下,摇一摇之前有做,但是效果不是类似微信那样的,所以照搬旧实现方案,采用github上人气略高的一个Device Accelerometer封装函数,这样就不用自己去爬各种坑了。

摇动事件是解决了,但想模拟声音、震动之类的,还得找一下新的api,因为之前没用过,所以大概收集了下资料,下面简单记录一下。

摇动就不再赘述了,简单几步,可以参考这里https://github.com/alexgibson/shake.js

var myShakeEvent = new Shake({

threshold: 15, // optional shake strength threshold

timeout: 1000 // optional, determines the frequency of event generation

});

myShakeEvent.start();

window.addEventListener('shake', shakeEventDidOccur, false);

//function to call when shake occurs

function shakeEventDidOccur () {

//put your own code here etc.

alert('shake!');

}

声音也简单,之前一直没用过HTML5新加的音视频接口,今天刚好试了试,还挺好用,加以下两个标签,默认不加任何诸如autoplay之类的属性,然后给个id,程序里通过id找到当前对象,调用play即可播放一次。

<audio id="run" src="js/shake_sound_male.mp3"></audio>
<audio id="match" src="js/shake_match.mp3"></audio>

再说震动,加以下判断,如果支持就调用震动,传入震动频率时长即可,不过实测后发现微信里面不支持,所以这项功能只有在微信外其他浏览器中才能得以体现。

navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;

下面附上整段HTML、CSS与JS代码,实现了css3过渡效果的滑动与JS滑动,也有打算使用CSS3 animation写,用animationEnd事件增加回调,但由于之前写抢红包游戏时发现腾讯出品的大部分内嵌浏览器不支持animationEnd回调事件,就忽略了此项,简单写了下,勿拍砖哈

HTML部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <meta name="msapplication-tap-highlight" content="no" />
    <title>摇一摇</title>
    <script src="js/shake.js"></script>
</head>
<body>
<div class="back">
    <div class="f">小红花</div>
</div>
<div id="fore" class="fore"></div>
<div class="move-wrap">
    <div id="up" class="up animate-up" style="display: none;"></div>
    <div id="down" class="down animate-down" style="display: none;"></div>
</div>
<audio id="run" src="js/shake_sound_male.mp3"></audio>
<audio id="match" src="js/shake_match.mp3"></audio>
</body>
</html>

CSS部分

* { margin: 0; padding: 0; box-sizing: border-box;}
        html,body { height: 100%;}
        .fore { background: url("images/shake.jpg") no-repeat center; background-size: 100% 100%; position: absolute; z-index: 3; width: 100%; height: 100%;}

        .move-wrap { width: 100%; height: 100%; overflow: hidden; position: relative;}
        .up { background: url("images/shake.jpg") no-repeat center top; background-size: 100% 200%; position: absolute; z-index: 3; width: 100%; height: 50%; top:0;}
        .down { background: url("images/shake.jpg") no-repeat center bottom; background-size: 100% 200%; position: absolute; z-index: 3; width: 100%; height: 50%; bottom: 0;}

        .animate-up {
            transition: top 1.5s linear;
            -webkit-transition: top 1.5s linear;
        }
        .animate-down {
            transition: bottom 1.5s linear;
            -webkit-transition: bottom 1.5s linear;
        }

        .back { background: #666; position: absolute; z-index: 1;width: 100%; height: 100%; color: #FFF;}
        .f { height: 22px; position: relative; top:50%; width: 100%; text-align: center; margin-top: -11px;}

JS部分

var shake = new Shake({
        threshold: 15,
        timeout: 1000
    }),
    run = document.getElementById('run'),
    match = document.getElementById('match'),
    fore = document.getElementById('fore'),
    up = document.getElementById('up'),
    down = document.getElementById('down');

    shake.start();

    var vibrate = function(){
        navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
        if (navigator.vibrate) {
            navigator.vibrate([500, 100, 100, 100, 500, 100, 100, 100, 500, 100, 100, 100,0]);
        }
    };

    var supportCss3 = function(style) {
        var prefix = ['webkit', 'Moz', 'ms', 'o'],
                i,
                humpString = [],
                htmlStyle = document.documentElement.style,
                _toHumb = function (string) {
                    return string.replace(/-(\w)/g, function ($0, $1) {
                        return $1.toUpperCase();
                    });
                };

        for (i in prefix)
            humpString.push(_toHumb(prefix[i] + '-' + style));

        humpString.push(_toHumb(style));

        for (i in humpString)
            if (humpString[i] in htmlStyle) return true;

        return false;
    };

    var ShakeAnimate = function(support){
        var begin = function(){
            fore.style.display='none';
            up.style.display='block';
            down.style.display='block';
        };

        var end = function(){
            if(!support&amp;&amp;isEnd) return ;
            isEnd =1;
            upStep = - upStep;
            downStep = - downStep;
            fore.style.display='block';
            up.style.top = '0px';
            up.style.display='none';
            down.style.bottom='0px';
            down.style.display='none';
            match.play();
            vibrate();
        };
        if(support){
            this.animate = function(){
                begin();
                setTimeout(function(){
                    up.style.top='-100px';
                    down.style.bottom='-100px';
                    setTimeout(function(){
                        up.style.top='0px';
                        down.style.bottom='0px';
                        setTimeout(function(){
                            end();
                            match.play();
                        },1500);
                    },2500);
                },0);
            };
        }else{
            var isEnd = 0;

            var openingSpeed = 8;
            var openedDelay = 2000;

            var moveMax = -100;

            var upStep = 1;
            var downStep = 1;

            var isUpBack = 0;
            var isDownBack = 0;

            var moveUp = function(){
                var top = parseFloat(up.style.top)||0;
                if(isUpBack&amp;&amp;top&gt;=0) {
                    end();
                    return;
                }
                up.style.top=top-upStep + 'px';
                if(isUpBack||top&gt;moveMax){
                    setTimeout(moveUp,openingSpeed);
                }else{
                    isUpBack = 1;
                    upStep = - upStep;
                    setTimeout(moveUp,openedDelay);
                }
            };

            var moveDown = function(){
                var bottom = parseFloat(down.style.bottom)||0;
                if(isDownBack&amp;&amp;bottom&gt;=0) {
                    end();
                    return ;
                }
                down.style.bottom=bottom-downStep + 'px';
                if(isDownBack||bottom&gt;moveMax){
                    setTimeout(moveDown,openingSpeed);
                }else{
                    isDownBack =1;
                    downStep = - downStep;
                    setTimeout(moveDown,openedDelay);
                }
            };

            this.animate = function(){
                isEnd = 0;
                isUpBack = 0;
                isDownBack = 0;
                begin();
                moveUp();
                moveDown();
            };
        }
    };

    var ani = new ShakeAnimate(supportCss3('transition'));

    window.addEventListener('shake', shakeEventDidOccur, false);

    function shakeEventDidOccur() {
        run.play();
        ani.animate();
    }

发现博客代码显示还是问题很大,一直没时间整个可以完美显示代码的主题,也不想再装插件,所以,还是直接去github上看吧,地址https://github.com/veryto/html5_shake