99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

canvas入門基礎(chǔ)(九):基礎(chǔ)動畫

2018-06-19 14:41 更新
實現(xiàn)動畫,我們首先想到的肯定是setTimeout和setInterval,這兩個在這里就不細(xì)說了。

除了這兩個外,我們還可以使用window.requestAnimationFrame()這個方法。

requestAnimationFrame 是專門為實現(xiàn)高性能的幀動畫而設(shè)計的一個API

window.requestAnimationFrame()這個方法是用來在頁面重繪之前,通知瀏覽器調(diào)用一個指定的函數(shù),以滿足開發(fā)者操作動畫的需求。這個方法接受一個函數(shù)為參,該函數(shù)會在重繪前調(diào)用。
注意: 如果想得到連貫的逐幀動畫,函數(shù)中必須重新調(diào)用 requestAnimationFrame()。
如果你想做逐幀動畫的時候,你應(yīng)該用這個方法。這就要求你的動畫函數(shù)執(zhí)行會先于瀏覽器重繪動作。通常來說,被調(diào)用的頻率是每秒60次,但是一般會遵循W3C標(biāo)準(zhǔn)規(guī)定的頻率。如果是后臺標(biāo)簽頁面,重繪頻率則會大大降低。

回調(diào)函數(shù)只會被傳入一個DOMHighResTimeStamp參數(shù),這個參數(shù)指示當(dāng)前被 requestAnimationFrame 序列化的函數(shù)隊列被觸發(fā)的時間。因為很多個函數(shù)在這一幀被執(zhí)行,所以每個函數(shù)都將被傳入一個相同的時間戳,盡管經(jīng)過了之前很多的計算工作。這個數(shù)值是一個小數(shù),單位毫秒,精確度在 10 μs。

參數(shù) callback 在每次需要重新繪制動畫時,會調(diào)用這個參數(shù)所指定的函數(shù)。這個回調(diào)函數(shù)會收到一個參數(shù),這個 DOMHighResTimeStamp 類型的參數(shù)指示當(dāng)前時間距離開始觸發(fā) requestAnimationFrame 的回調(diào)的時間。 返回值 requestID 是一個長整型非零值,作為一個唯一的標(biāo)識符.你可以將該值作為參數(shù)傳給 window.cancelAnimationFrame() 來取消這個回調(diào)函數(shù)。

//動畫循環(huán) if (!window.requestAnimationFrame) { window.requestAnimationFrame = (window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function (callback) { return window.setTimeout(callback, 17 ); }); }


 if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = (window.cancelRequestAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame || window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame || window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame || window.clearTimeout); }

例子:

var cc = document.getElementById("canvas");   

var cxt = cc.getContext("2d");   

var ca = document.createElement("canvas");   

ca.width=500;   

ca.height=500;   

var cxt2 = ca.getContext("2d");   

var x = y = 0;  

//加載多個圖片

function loadImages(sources, callback) {  

    var count = 0,    

    images = {},   

    imgNum = 0;   

    for (k in sources) {   

        imgNum++;   

    }    

    for (k in sources) {   

        images[k] = new Image();   

        images[k].onload = function() {   

            if (++count >= imgNum) {   

                callback(images);   

            }   

        }   

        images[k].src = sources[k];   

    }   

}   

var sources = []; 


function drawGameImage() {    

    sources = ["gameimage/0.png", "gameimage/1.png", "gameimage/2.png", "gameimage/3.png", "gameimage/4.png", "gameimage/5.png", "gameimage/6.png", "gameimage/7.png", "gameimage/8.png", "gameimage/2.png", "gameimage/3.png", "gameimage/4.png", "gameimage/5.png", "gameimage/6.png", "gameimage/9.png", "gameimage/10.png"];     //調(diào)用圖片預(yù)加載函數(shù),實現(xiàn)回調(diào)函數(shù)     

    loadImages(sources, function(images) {   

        var x = y = 0;   

        for (var i = 0; i < sources.length; i++) {   

            cxt2.drawImage(images[i], x * 100, y * 100, 100, 100);   

            if (i < 4) {

                 x++; 

             } else if (i >= 4 && i < 8) {   

                  y++;   

             } else if (i >= 8 && i < 12) {   

                  x--;   

             } else {   

                   y--;

             } 

        }    

     });   

}    

drawGameImage();   

var times = Math.floor(Math.random() * 10) + sources.length * 2;   

var v = 0;    

function move() {   

     var moveX = 400;

     var speed = 100; 

     if (x < moveX && y == 0) {   

        x += speed;

     } else if (x == moveX && y < moveX) { 

        y += speed;   

     } else if (y == moveX && x > 0) {   

         x -= speed;   

     } else if (x == 0 && y > 0) {   

         y -= speed;   

     }   

     cxt.clearRect(0, 0, 500, 500);   

     cxt.drawImage(ca,0,0,500,500);   

     cxt.fillStyle = "rgba(0,0,0,.5)";   

     cxt.fillRect(x, y, 100, 100);   

     if (v > times) {   

         cancelAnimationFrame();   

     }   

     v++;   

      requestAnimationFrame(move);   

}   

move();



我們來逐一看看:

首先是加載多個圖片問題,我在這里封裝了一個loadImages(sources,callback)方法,其中sources是一個圖片路徑數(shù)組,callback是圖片加載完成后的回調(diào)函數(shù)。

function loadImages(sources, callback) { var count = 0, images = {}, imgNum = 0; for (k in sources) { imgNum++; } for (k in sources) { images[k] = new Image(); images[k].onload = function() { if (++count >= imgNum) { callback(images); } } images[k].src = sources[k]; } }   


注意:
  1. 在loadImages方法中,我們應(yīng)該先綁定image.onload事件,后加載圖片
原因:如果圖片從緩存中加載,速度非常快以至于沒來得及綁定事件就加載完畢,自然不會觸發(fā)綁定事件。

  1. for...in循環(huán) 與 for循環(huán)的區(qū)別
for循環(huán)用于迭代數(shù)組(array) for...in循環(huán)用于迭代對象(object, {})或者關(guān)聯(lián)數(shù)組(hash array)

由于我們的背景是不需要變化,而滾動框是需要不停的重繪渲染,所以我們這里創(chuàng)建了一個新的canvas,將背景圖繪制在這個canvas上,然后將這個canvas作為圖片源,繪制在第一個canvas里。

var ca = document.createElement("canvas"); ca.width=500; ca.height=500; var cxt2 = ca.getContext("2d");   


 drawGameImage();   

當(dāng)然,你也可以用分層canvas來分開不需頻繁渲染的圖形和需要頻繁重繪渲染的圖形。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號