在画布上下文中闪烁

时间:2014-03-10 18:14:09

标签: javascript canvas

我正在使用this code在页面上绘制等待进度的内容:

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Preloaders</title>
        <link rel="stylesheet" href="css/index.css" />
        <link rel="stylesheet" href="css/preloaders.css" />

        <script src="js/lib/requestAnimFrame.js"></script>
        <script src="js/lib/timer.js"></script>
        <script src="js/lib/preloaders.js"></script>

        <script src="js/app.js"></script>
    </head>
    <body>
        <div id="preloader1"></div>
    </body>
</html>

index.css:

html, body{
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

preloader.css:

#preloader1 {
    display: block;
    width: 100%;
    height: 15px;
    margin: 0;
    padding: 0;
}

requestAnimFrame.js:

window.requestAnimFrame = (function(callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
        window.setTimeout(callback, 1000 / 60);
    };
})();

timer.js:

var Timer = function(){
    "use strict";

    var prev = new Date().getTime();
    var speed = 1;

    this.start = function(){
        prev = new Date().getTime();
    }

    this.setSpeed = function ( s ) {
        speed = s;
    }

    this.getDelta = function( inSeconds ){

        var now = new Date().getTime();
        var delta = (now - prev) * speed;
        if (inSeconds) delta /= 1000;
        prev = now;
        return delta;

    }

}

preloaders.js:

var PRELOADERS = {
    waiting1: function ( el ) {
        "use strict";

        var width  = el.offsetWidth;
        var height = el.offsetHeight;
        var speed  = 1;

        var v = [0, 0, 0, 0]; // values
        var e = [0, -0.5, -1, -1.5]; // elapsed

        var canvas = document.createElement( "canvas" )
        canvas.style.display = "block";
        canvas.width         = width;
        canvas.height        = height;

        el.appendChild( canvas );

        var ctx = canvas.getContext('2d');

        var c = [ // colours
            [255,60,60],  // red
            [255,200,60], // yellow
            [80,220,40],  // green
            [40,120,220]  // blue
        ]

        var o = [0,1,2,3]; // order

        var drawRect = function ( w /* width: 0..1 */, c /* colour: [r,g,b | a] */ ) {

            if (c.length == 4) ctx.fillStyle = "rgba("+c[0]+","+c[1]+","+c[2]+","+c[3]+")";
            else ctx.fillStyle = "rgb("+c[0]+","+c[1]+","+c[2]+")";

            var hw = width / 2; // half-width
            ctx.fillRect( hw-hw*w, 0, width*w, height );

        }

        var easing = function ( val ) {
            return -val*(val -2)
        }

        var next = function ( ) {
            var ot = o.slice(0);
            o = [ot[1], ot[2], ot[3], ot[0]];
        }

        this.update = function ( delta ) {

            for (var i = 0; i < 4; i++) {

                e[i] += delta * speed;

                if (e[i] > 2) {
                    e[i] = 0;
                    next();
                }

                v[i] = easing( Math.min(1, Math.max(0, e[i])) );

                drawRect( v[o[i]], c[o[i]] );

            }

        }

        this.setSpeed = function ( s ) {
            speed = s;
        }

    }
}

app.js:

var init = function(  ){
    "use strict";

    var timer = new Timer();
    var preloader1 = new PRELOADERS.waiting1( document.getElementById( "preloader1" ) );
    // preloader1.setSpeed(0.1);

    var animate = function( ) {
        render( );
        requestAnimFrame( animate );
    }

    var render = function( ){
        var delta = timer.getDelta( true );
        preloader1.update( delta );
    }

    animate();

}

window.onload = init;

但有时画布上的矩形会闪烁。 请帮我抓住这个bug。

1 个答案:

答案 0 :(得分:0)

问题在于更新功能。 在所有计算之后,应该在单独的循环中调用drawRect:

this.update = function ( delta ) {

    for (var i = 0; i < 4; i++) {

        e[i] += delta * speed;

        if (e[i] > 2) {
            e[i] = 0;
            next();
        }

        v[i] = easing( Math.min(1, Math.max(0, e[i])) );

    }

    for (i = 0; i < 4; i++) {
        drawRect( v[o[i]], c[o[i]] );
    }

}