画布对象闪烁

时间:2015-12-15 07:39:01

标签: javascript object canvas html5-canvas

我的画布动画中有一些眼睛闪烁。我不知道导致闪烁的原因是什么,谷歌没有提供我在文本中添加的转换全局元素的帮助。在单独的画布上,它们工作正常。只有当我将它们添加到主代码中时才会遇到闪烁。

    var canvas,
        context,
        ox = 60,
        oy = 60,
        ux = Math.random(),
        uy = Math.random();
    var drops = [];
    var squares = [];
    var clouds = [];
    var text, step = 190, steps = 255;
            delay = 180;
    var rgbstep = 120;


    function Drop(x,y,color){
        this.x = x;
        this.y = y;
        this.color = color;
        this.dy = Math.random();
    }


    function Square(x,y,w,color){
        this.sx = x;
        this.sy = y;
        this.sw = w;
        this.color = color;
        this.qy = Math.random();
    }







    function init(){
        canvas = document.getElementById('canvas');
        context = canvas.getContext('2d');
        //alert("Hello!\nClick on the screen for rain drops!");
        window.addEventListener('resize', resizeCanvas, false);
        window.addEventListener('orientationchange', resizeCanvas, false);
        resizeCanvas()
        Textfadeup(); 
        canvas.onclick = function(event){
            handleClick(event.clientX, event.clientY);
        };
        setInterval(handleClick,50);
        setInterval(draw, 1);





    }



      addEventListener("keydown", function(event) {
        if (event.keyCode == 32)
          document.body.style.background = "yellow";


      });
      addEventListener("keyup", function(event) {
        if (event.keyCode == 32)
          document.body.style.background = "";
    });




    function handleClick(x,y,w){
        var found = false;
        for(var i = 0; i<drops.length; i++){
            d = Math.sqrt((drops[i].x-x)*(drops[i].x-x) + (drops[i].y-y)*(drops[i].y-y));
            if(d<=5){
                drops.splice(i,1);
                found = true;
            }
        }

        fillBackgroundColor();
        if(!found){
        var colors = ["#000080", "#add8e6", "blue"];
        var color = colors[Math.floor(Math.random()*colors.length)];
            drops.push(new Drop(x,y,color));
            squares.push(new Square(x,y,w,color));

        }

                for(var i = 0; i<drops.length; i++){
            drawDrop(drops[i]);
        }
                for(var i = 0; i<squares.length; i++){
            drawSquare(squares[i]);
        }

    }







    function Textfadeup() {
                rgbstep++;
                //context.clearRect(0, 0, canvas.width, canvas.height);
                context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
                context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
                context.font= "40px Arial";
                if (rgbstep < 255)
                    var t = setTimeout('Textfadeup()', 10);
                if (rgbstep == 255) {
                    Textfadedown();
                }
    }

    function Textfadedown() {
             rgbstep=rgbstep-1;
               // context.clearRect(0, 0, canvas.width, canvas.height);
                context.fillStyle = "rgb(" + rgbstep + "," + rgbstep + "," + rgbstep + ")"
                context.fillText("Drip, drip, drop, little April shower...", 500, canvas.height);
                context.font= "40px Arial";
                if (rgbstep > 30)
                    var t = setTimeout('Textfadedown()', 10);
                if (rgbstep == 30) {
                    Textfadeup();
                }
            }   






     /* function drawDrop(drop){
        context.beginPath();
        context.moveTo(drop.x,drop.y);
        context.lineTo(drop.x+10,drop.y+25);
        context.lineTo(drop.x+13,drop.y+32);
        context.lineTo(drop.x+46,drop.y+50);
        context.lineTo(drop.x+72,drop.y+51);
        context.lineTo(drop.x+81,drop.y+43);
        context.lineTo(drop.x+104,drop.y+52);
        context.lineTo(drop.x+111,drop.y+46);
        context.lineTo(drop.x+83,drop.y+40);
        context.lineTo(drop.x+75,drop.y+20);
        context.lineTo(drop.x+57,drop.y+8);
        context.closePath();
        context.fillStyle = 'orange';
        context.fill();
        if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
            drop.dy != -drop.dy;
        drop.y += drop.dy;
    };



    function drawDrop(drop){
        context.beginPath();
        context.moveTo(drop.x,drop.y);
        context.beginPath();
        context.moveTo(drop.x,drop.y);
        context.lineTo(drop.x+24,drop.y);
        context.lineTo(drop.x-2,drop.y+25);
        context.lineTo(drop.x+17,drop.y+25);
        context.lineTo(drop.x-18,drop.y+53);
        context.lineTo(drop.x-3,drop.y+54);
        context.lineTo(drop.x-47,drop.y+77);
        context.lineTo(drop.x-31,drop.y+59);
        context.lineTo(drop.x-40,drop.y+59);
        context.moveTo(drop.x-40,drop.y+59);
        context.moveTo(drop.x-14,drop.y+33);
        context.lineTo(drop.x-30,drop.y+32);
        context.closePath();
        context.fillStyle = 'yellow';
        context.fill();
        if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
            drop.dy != -drop.dy;
        drop.y += drop.dy;
    };*/



    function drawDrop(drop){
        context.beginPath();
        context.arc(drop.x, drop.y, 5, 0, Math.PI);
        context.fillStyle = drop.color;
        context.moveTo(drop.x - 5, drop.y);
        context.lineTo(drop.x, drop.y - 7);
        context.lineTo(drop.x + 5, drop.y);
        context.closePath();
        context.fill();
        if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
            drop.dy != -drop.dy;
        drop.y += drop.dy;
    };


    function drawSquare(square){
        var sw = Math.floor(4);
        var sx = Math.floor(Math.random() * canvas.width);
        var sy = Math.floor(Math.random() * canvas.height);
        context.beginPath();
        context.rect(sx, sy, sw, sw); 
        context.fillStyle = '#add8e6';
        context.fill();

    };


    function drawCloud(ox,oy) {
             context.beginPath();
             context.moveTo(ox,oy);
             context.bezierCurveTo(ox-40, oy+20, ox-40, oy+70, ox+60, oy+70);
             context.bezierCurveTo(ox+80, oy+100, ox+150, oy+100, ox+170, oy+70);
             context.bezierCurveTo(ox+250, oy+70, ox+250, oy+50, ox+220, oy+20);
             context.bezierCurveTo(ox+260, oy-40, ox+200, oy-50, ox+170, oy-30);
             context.bezierCurveTo(ox+150, oy-75, ox+80, oy-10, ox+170, oy+5);
             context.bezierCurveTo(ox+30, oy-75, ox-20, oy-60, ox, oy);
             context.closePath();
             context.fillStyle = 'white';
             context.fill();

    };

    function fillBackgroundColor(){
        context.fillStyle = 'gray';
        context.fillRect(0,0,canvas.width,canvas.height);
    }
    function resizeCanvas(){
        canvas.width = window.innerWidth - 20;
        canvas.height = window.innerHeight - 20;
        for(var i = 0; i<drops.length; i++){
            drawDrop(drops[i]);
        }
         for(var i = 0; i<squares.length; i++){
            drawSquare(squares[i]);
        }

    }

    function draw() {
      drawCloud(ox, oy, 500);
      if (ox + ux > canvas.width || ox + ux < 0)
        ux = -ux;   
        if (oy + uy > canvas.height || oy + uy < 0)
        uy = -uy;
      ox += ux;
     }





    function degreesToRadians(degrees) {
            return (degrees * Math.PI)/180;
        }
    window.onload = init;

    </script>
    <body>
    <canvas id='canvas' width=500 height=500></canvas>
    </body>

1 个答案:

答案 0 :(得分:0)

您不应该使用setInterval渲染到画布。您已将时间设置为10,这比屏幕刷新率更快。您的代码没有简单的解决方法,因为它有点复杂。

您需要做的是设置一个主循环。从该功能,您可以完成每个动画帧所需的一切。在该功能结束时,您使用np.array来请求下一帧。它将动画与显示刷新率同步并停止闪烁。

实施例

id

要启动它,请从window.requestAnimationFrame(mainLoop)功能

调用function mainLoop(){ drawCloud(); // draw your cloud // other stuff did not get a chance to see what else you did. // request the next animation frame that should occur in 1/60th of a second. requestAnimationFrame(mainLoop); }
mainLoop

除了非常短的简单函数或长时间段之外,不应该使用setInterval。每当我看时,它都会导致你的jsFiddle崩溃。