2015-12-15 90 views
0

我的眼睛在我的畫布動畫中閃爍。我不知道是什麼原因導致了閃爍,Google不會爲我添加到我的文本中的過渡全局元素提供幫助。在單獨的畫布上,它們工作正常。只有當我將它們添加到主代碼時,我纔會遇到閃爍。畫布對象閃爍

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> 

回答

0

您不應該使用setInterval渲染到畫布。您已將時間設置爲10,這比屏幕刷新率更快。因爲它有點複雜,所以不容易修復你的代碼。

你需要做的是設置一個主循環。通過該功能,您可以爲每個動畫幀執行所需的一切。在該功能結束時,您使用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); 
} 

要從init功能

mainLoop(); // starts it all happening 

你永遠不應該使用setInterval的任何東西,但很短的簡單的功能或長的時間段啓動它所有的呼叫mainLoop。它讓你的jsFiddle在每次查看時都會崩潰選項卡。

+0

好的。那麼爲什麼呢,即使我告訴setInterval命令與handleClick函數對話,它最終會影響文本和雲形狀? –

+0

您應該將所有呈現調用收集到一個調用中。正如你所看到的那樣,'handleClick'函數干擾了'雲功能',特別是因爲它們的時序不同。最好將所有的邏輯和所有的渲染組合在一起。渲染應儘可能簡單,邏輯處理所有複雜的交互。 – Blindman67