最近項目閒着沒什麼事,又想起了canvas, 針對移動端設備默認瀏覽器,做了點渲染方面效率的測試,手頭設備不多(有一些低端機型和pc chrome做對比),現將測試數據分享給大家吧,本想和css3 animation動畫一起測試比較一下,發現animation水的不行,效果跟canvas差很多(可能是因為我代碼寫的不好),webgl還沒有普及到移動設備,所以也不做比較了,曾經看過一篇文章drawImage比putImageData效率低,但測試了一下drawImage的性能更好,還請大牛指導。測試使用cocos2dx的dancer做動畫,全屏幕刷新,沒使用髒矩形刷新,根據動畫個數,屏幕縮放大小兩方面測試(值為fps):



1

10

50

100

200

500

1000

1

20

50

100

200

500

1000

1

10

50

100

200

500

1000

1

10

50

100

200

500

320*200

 V

V

V

V

V

V

 V

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

480*320

 

 

 

 

 

 


V

V

V

V

V

V


 

 

 

 

 

 

 

 

 

 

 

 

 

 

800*480

 

 

 

 

 

 

 

 

 

 

 

 

 


V

V

V

V

V

V

 V

 

 

 

 

 

 

 

1024*800

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


V

V

V

V

V

V

 V

chrome

75

75

75

75

73

46

46

75

73

72

67

62

41

26

61

59

58

56

53

34

20

29

29

29

29

27

21

14

chiwi v88

165

108

55

36

25

12

8

116

83

46

36

23

12

6

61

57

43

30

21

10

6

53

48

35

27

18

6

6

moto ME722

78

55

22

12

8

4

2

76

47

16

11

7

4

2

43

30

17

12

7

4

2

23

23

17

12

8

4

2

iphone 4

61

61

60

58

43

22

12

61

61

61

54

42

22

12

61

61

57

48

38

22

12

49

50

46

39

32

21

12

GALAXY SII

79

60

27

16

14

9

6

77

55

25

14

10

7

4

75

54

26

16

8

6

4

50

37

26

12

8

5

3

做了幾張圖方便大家對比:

不同分辨率(這裏網頁縮放使用meta標籤適配全屏):

TypeScript圖形渲染實戰pdf下載_v8

TypeScript圖形渲染實戰pdf下載_i++_02

TypeScript圖形渲染實戰pdf下載_v8_03

TypeScript圖形渲染實戰pdf下載_v8_04

 

不同機型(chiwi v88為馳為v88,具體配置大家自查吧):

TypeScript圖形渲染實戰pdf下載_i++_05

TypeScript圖形渲染實戰pdf下載_v8_06

TypeScript圖形渲染實戰pdf下載_i++_07

TypeScript圖形渲染實戰pdf下載_i++_08

結果iphone必須是最牛的,貌似最高有60fps的渲染限制,以上測試僅供參考(僅僅是渲染部分,沒有邏輯代碼),希望能幫到大家(^-^)

後附部分代碼(有些的不好的地方求指導)註釋前部分是putImageData渲染,後部分是使用css3 animation

$(document).ready(function(e)
{
    var canvas=document.getElementById("canvas");
    var tag = document.getElementById("tag");

    var sprite_info = {"s":"dance_atlas.png", 'w':85, 'h':120, 'f':[[0, 0], [85, 0], [170, 0], [255, 0], [340, 0], [0, 120], [85, 120], [170, 120], [255, 120], [340, 120], [0, 240], [85, 240], [170, 240], [255, 240]], "fd":[]};

    var sprites=[];

    var SPEED = 60;

    var image_data = null;
    var image_ele = new Image();
    var data = null;
    var timestamp;
    var fps = 60;

    var canvas_width = canvas.width;
    var canvas_height = canvas.height;
    var canvas_context = canvas.getContext('2d');

    image_ele.src = sprite_info.s;
    image_ele.onload = function()
    {
        var i = 0;
        //getImageData();
        while(i<1)
        {
            createParticles();
            i++
        }
        start();
    }

    function drawloop()
    {
        updateParticles();
        drawParticles();
    }

    /*function putloop()
    {
        updateParticles();
        putParticles();
    }*/

    /*function getImageData()
    {
        canvas_context.drawImage(image_ele, 0, 0, image_ele.width, image_ele.height);
        for(var index = sprite_info.f.length - 1; index > -1; index--)
        {
            var cf = sprite_info.f[index];
            sprite_info.fd[index] = canvas_context.getImageData(cf[0], cf[1], sprite_info.w, sprite_info.h);
        }
    }*/

    function createParticles()
    {
        var sp = Math.floor(Math.random() * SPEED);
        sprites.push(
        {
            x: Math.floor(Math.random() * (canvas_width - sprite_info.w)),
            y: Math.floor(Math.random() * (canvas_height - sprite_info.h)),
            s: sp,
            cs: 0,
            i:0
        });
    }

    canvas.addEventListener('click',createParticles, false);
    canvas.addEventListener('touchstart',createParticles, false);

    function updateParticles()
    {
        for(var index = sprites.length - 1; index > -1 ;index--)
        {
            var sprite = sprites[index];
            if(sprite.cs == 0)
            {
                sprite.cs = sprite.s;
                if(sprite.i == sprite_info.f.length - 1)
                    sprite.i = 0;
                else
                    sprite.i++;
            }
            else
            {
                sprite.cs--;
            }
        }
    }

    function drawParticles()
    {
        canvas_context.clearRect(0,0,canvas.width,canvas.height);
        for(var index = sprites.length - 1; index > -1 ;index--)
        {
            var sprite = sprites[index];
            var frame_i = sprite_info.f[sprite.i];
            canvas_context.drawImage(image_ele, frame_i[0], frame_i[1], sprite_info.w, sprite_info.h, sprite.x,sprite.y, sprite_info.w, sprite_info.h);
        }
    }

    function putParticles()
    {
        canvas_context.clearRect(0,0,canvas.width,canvas.height);
        for(var index = sprites.length - 1; index > -1 ;index--)
        {
            var sprite = sprites[index];
            var frame_i_d = sprite_info.fd[sprite.i];
            canvas_context.putImageData(frame_i_d, sprite.x,sprite.y);
        }
    }

    var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(func){setTimeout(func, 0);},
    startTime = window.mozAnimationStartTime || Date.now(), fra = 0;

    function updateProgress(){
        drawloop();
        var drawStart = (timestamp || Date.now());
        fra++;
        if(drawStart - startTime > 1000)
        {
            tag.innerText = "fps:" + fra;
            startTime = drawStart;
            fra = 0;
        }
        if (true){
            requestAnimationFrame(updateProgress);
        }
    }

    function start()
    {
        requestAnimationFrame(updateProgress);
    }







   /* var pnl = document.getElementById("app");
    var SPEED = 10;
    var spy = null;
    var fps = 60;

    var r_time = Math.floor((1000 / fps) * 14);


    function createParticles()
    {
        var new_dancer = document.createElement("div");
        var inner = document.createElement("div");
        new_dancer.appendChild(inner);
        pnl.appendChild(new_dancer);
        new_dancer.style["left"] = Math.floor(Math.random() * (/(\d+)px/.exec(pnl.style["width"])[1] * 1 - sprite_info.w)) + 'px';
        new_dancer.style["top"] = Math.floor(Math.random() * (/(\d+)px/.exec(pnl.style["height"])[1] * 1 - sprite_info.w)) + 'px';
        //var sp = Math.floor(Math.random() * SPEED);
        inner.style['-webkit-animation-duration'] = r_time + 'ms';
        sprites.push(new_dancer);
        spy = new_dancer;
    }

    var drawStart, startTime = Date.now(), fra = 0, timestamp;

    function updateProgress(){
        debugger;
        var drawStart = (timestamp || Date.now());
        fra += 14;
        if(drawStart - startTime > 1000)
        {
            debugger;
            tag.innerText = "fps:" + fra;
            startTime = drawStart;
            fra = 0;
        }
    }



    function start()
    {
        var i = 0;
        while(i<100)
        {
            createParticles();
            i++
        }
        spy.addEventListener("webkitAnimationIteration", updateProgress, false);
    }



    start();*/



});