天天看點

HTML5 搖一搖加強版之一次失敗的探索

最近在看裝置傳感器的API,當然也少不了研究一下讓微信稱神的“搖一搖”了。關于“搖一搖”的實作,網上很多資料是以不詳細說了,但總是有布局、效果不全等各種問題,這裡整理一個比較完整的版本。

最近在看裝置傳感器的API,當然也少不了研究一下讓微信稱神的“搖一搖”了。關于“搖一搖”的實作,網上很多資料是以不詳細說了,但總是有布局、效果不全等各種問題,是以作為一名資深copypaster,代碼肯定是要貼的: 源碼在此 

手機掃二維碼看看效果,支援Chrome、Safari、微信(新版):

HTML5 搖一搖加強版之一次失敗的探索
核心代碼是這一段:

this.deviceMotionHandler = function(eventData) {        
    var acceleration = eventData.acceleration;   
    var curTime = new Date().getTime();         
    //檢測頻率:每100ms一次
    if ((curTime - that.last_update) > 100) {     
        var diffTime = curTime - that.last_update;      
        that.last_update = curTime;     
        that.x = acceleration.x;            
        that.y = acceleration.y;         
        that.z = acceleration.z;      
        var speed = Math.abs(that.x + that.y + that.z - that.last_x - that.last_y - that.last_z) / diffTime * 10000;            
        if (speed > that.SHAKE_THRESHOLD) {  
            //do something
            that.shakeAudio.play();        //搖一搖音效
            window.navigator.vibrate(200);    //振動效果
            that.shakeEffect.className = 'shake-box shaking';    //搖一搖圖檔動态
            clearTimeout(shakeTimeout);         
            var shakeTimeout = setTimeout(function() {
                that.shakeEffect.className = 'shake-box';
            },4000);           
        }    
        that.last_x = that.x;      
        that.last_y = that.y;               
        that.last_z = that.z;         
    }        
};      

原理:  以100ms的間隔去掃描加速度計,當檢測到加速度發生突變(變化率大于閥值)時,就可以認為此時在甩動手機。由公式可以看到,這裡檢測的是3個方向的加速度,是以無論往什麼方向甩都可以觸發搖一搖效果。

注意點: 這裡加了一個搖一搖的音效,移動端關于音頻的坑太多,想必各位也是碰到不少。本次的坑是即使調用了play也無法播放,解決辦法是讓使用者操作第一次播放或者加載,具體來說就是綁定一個事件,如下。而且加載需要一定時間,這裡本來應該再做緩沖處理,但我沒有,是以第一次播放會有很明顯的延遲。

window.addEventListener('touchstart',function () {
        if ( !shake1.audioLoaded ) {
            shake1.shakeAudio.load();  //load事件必須由使用者觸發
            shake1.audioLoaded = true;
        }
}, false);      

布局方面: 布局方面嘗試使用了CSS3的彈性盒子,但是萬萬沒想到先進的X5核心居然僅支援 display: -webkit-box; 是以這裡需要多寫一套相容的樣式。動态效果本來想用 transition 湊合一下,看了效果還是過不了自己這關,最後還是換成 animation 實作。transition的問題是撐開和收縮時邊框的行為不對,用動畫就比較好解決了。布局需要注意的是:背景圖的上半部需要多加一層嵌套實作自适應。另外,微信的邊框還有陰影,這些細節咱們暫時先忽略了。HTML結構如下:

<div class="bodymask"><h2>準備好了嗎?<br />點選螢幕開始"搖"!</h2></div>
<div class="shake-box">
    <div class="shake-upside">
        <div class="shake-upside-inner"></div>
    </div>
    <div class="shake-backimage">
        <a href="http://www.cnblogs.com/qieguo/"><img id="id-shake-image" src="source/000.png"/></a>
    </div>
    <div class="shake-downside"></div>
</div>      

效果圖: 

HTML5 搖一搖加強版之一次失敗的探索
HTML5 搖一搖加強版之一次失敗的探索

以上實作了“搖一搖”效果,但以樓主當然不會到此為止。下面是樓主失敗而有益的探索(“有益”二字可無視)

樓主的瞎搞

其實樓主是一個吃飯都不想動手的重度懶癌患者,拿着手機看得正爽的時候還要我伸出中指去點選螢幕或者滑動,真的好累啊。。。特别是在躺着的時候,拇指是一個受力點,既要支撐手機還要伸出去滑動螢幕,很不自然。是以,為什麼不能甩一甩就翻頁呢? 比如說下面的場景:

HTML5 搖一搖加強版之一次失敗的探索

分析:

這個需求貌似很簡單的樣子,加速度是有方向的,直接判斷x軸加速度正負不就能判斷是左甩還是右甩了嗎? 搖一搖的代碼稍微改改貌似就能實作了呢,竊喜~~~然而,理想總是太豐滿,而現實卻太骨感。無論我們往哪個方向甩動,最後要停止還是需要加一個阻力,是以一次甩動過程中至少有一次加速度方向的變化。請注意,這裡有個“至少”,因為有時候我們要向左甩的時候,可能開始會先向右退一點才左甩的;在刹停的時候也很有可能刹過頭了,這裡加速度就會有一個抖動。

HTML5 搖一搖加強版之一次失敗的探索
HTML5 搖一搖加強版之一次失敗的探索
HTML5 搖一搖加強版之一次失敗的探索

 想象總是沒說服力,我們還是看看資料吧。當然這裡先利用搖一搖類似的篩選規則來去掉非甩動的動作。當檢測到加速度發生突變(變化率大于閥值)時認為發生了一次甩動,這時候輸出 x 軸的加速度值來看看,掃描頻率設定為100ms的時候資料如下:

HTML5 搖一搖加強版之一次失敗的探索
HTML5 搖一搖加強版之一次失敗的探索

上面分别是左甩和右甩時候的資料,根據這個資料特點,判斷每一個周期的第一個符合條件的加速度正負就可以判斷甩動的方向了,樓主這裡定義每個甩動周期為1s。

var speed = Math.abs(that.x + that.y + that.z - that.last_x - that.last_y - that.last_z) / diffTime * 10000;            
if (speed > that.SHAKE_THRESHOLD) {  
    if ((curTime - that.last_catch) > 1000) {
        if (that.x > 5) {
            output.innerHTML += '右甩x:' + that.x + '<br/>';  //加速度向右,右甩
            that.last_catch = curTime;
        } else if( that.x < -5) {
            output.innerHTML += '左甩x:' + that.x + '<br/>';  //加速度向左,左甩
            that.last_catch = curTime;
        }
     }
}      

理論上這個是可以篩選掉不适合的加速度資料了,測試如下:

HTML5 搖一搖加強版之一次失敗的探索
HTML5 搖一搖加強版之一次失敗的探索

看起來像是得到了準确的結果,但不同人有不同的習慣、力度,上面的方法并不能很好的得到最準确的辦法。

更為準确的辦法應該是求出x的位移,再加上 x軸加速度變化判斷是否甩動,兩者結合就可以很好的判斷甩動方向了。這裡位移隻要求能判斷左右,是以直接用高中實體的公式即可。但是,在測試了 n 次之後,我才開始想,這個需求是真實存在的嗎?還是說隻存在我的臆想裡面? 突然想起紅衣教主的話,很多人啊都是掌握一門技術之後呢就會把這個技術包裝成一個産品,還會強行為這個産品适配很多需求,但這些需求都是YY,都是僞需求!

真理!老周這一針見血啊!

不過呢,加速度計和陀螺儀還是非常好玩的東西,好好利用它們還是可以實作很多有趣的東西,比如說這個:AIWI使用手機玩體感遊戲。

隻要你能利用加速度計和陀螺儀計算出空間中的運動軌迹,那這一切都好辦了,不過要得到比較好的精度可不能用高中實體那種簡單的時域積分哦,這個樓主就不敢強行裝逼了,有興趣的同學自行搜尋哈。

以上,這一篇都實在太水了,還是放圖吧。

HTML5 搖一搖加強版之一次失敗的探索

(圖檔出處:小周同學,轉載請注明)

 原創文章,轉載請注明出處!本文連結:http://www.cnblogs.com/qieguo/p/5448786.html  

繼續閱讀