読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

iPhoneを振ったときにイベントを発火する

iPhoneを振っているときと振ってないとき用の関数を渡すと一定時間毎に実行するクラスをつくりました。
現状はインスタンスを返しませんが、のちのちメソッドを実装したいと思っているので new で実行しています。

ソースコード

/**
 * opt_moveFunc // iPhoneを振っているときに発火するイベント
 * opt_moveFunc // iPhoneを振っていないときに発火するイベント
 * opt_intaval // つぎのイベントが発生するまでのインターバル(省略すると0.1秒)
 * opt_level // 加速度のしきい値(省略すると1)
 */
function AccEvent(opt_moveFunc, opt_stopFunc, opt_intarval, opt_level) {

    "use strict";
    
    var win                = window,
        doc                = document,
        throttle           = new Throttle(opt_intarval || 100),
        body               = doc.body,
        qax                = [],
        qay                = [],
        qaz                = [],
        i                  = 0,
        moveFlag           = false,
        moveFunc           = opt_moveFunc || function() {},
        stopFunc           = opt_stopFunc || function() {},
        CACHE_LENGTH       = 1,
        START_ACCELERATION = opt_level || 1;

    init();
    
    function init() {
        win.addEventListener("devicemotion", handleDeviceMotion, false);
    }
    
    function handleDeviceMotion(evt) {
        throttle.exec(function() {
            var ax = evt.acceleration.x,
                ay = evt.acceleration.y,
                az = evt.acceleration.z,
                gx = evt.accelerationIncludingGravity.x,
                gy = evt.accelerationIncludingGravity.y,
                gz = evt.accelerationIncludingGravity.z,
                ra = evt.rotationRate.alpha,
                rb = evt.rotationRate.beta,
                rg = evt.rotationRate.gamma;

            qax[i] = ax;
            qay[i] = ay;
            qaz[i] = az;

            if (qax.length > CACHE_LENGTH - 1) {
                if (ave(qax) > START_ACCELERATION && ave(qay) > START_ACCELERATION && ave(qaz) > START_ACCELERATION) {
                    moveFlag = true;
                    moveFunc();
                } else {
                    moveFlag = false;
                    stopFunc();
                }
            }
                        
            i = ++i % CACHE_LENGTH;
        });
        
        function ave(arr) {
            var length = arr.length,
                i      = length,
                sum    = 0;
            
            while (i--) {
                sum += Math.abs(arr[i]);
            }

            return sum / length;
        }
    }

    function Throttle(minInterval) {
        var _timeStamp = 0,
            _timerId;
        
        function exec(func) {
            var now   = +new Date,
                delta = now - _timeStamp;
            
            clearTimeout(_timerId);
            if (delta >= minInterval) {
                _timeStamp = now;
                func();
            } else {
                _timerId = setTimeout(function() {
                    exec(func);
                }, minInterval - delta);
            }
        }

        return {
            exec : exec
        };
    }
}

つかいかた

new AccEvent(
    function() {
        console.log("move");
    },
    function() {
        console.log("stop");
    },
    100,
    1
);