2015-12-15 2 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); 
} 

начать все вызов mainLoop из init функции

mainLoop(); // starts it all happening 

Вы никогда не должны использовать setInterval для чего-нибудь, но очень короткие простые функции или длительные периоды времени. Это заставило ваш jsFiddle сбрасывать вкладку каждый раз, когда я смотрел.

+0

Хорошо. Так почему же, хотя я говорю команде setInterval, чтобы поговорить с функцией handleClick, это в конечном итоге влияет на текст и форму облака? –

+0

Вы должны собрать все вызовы визуализации в один звонок. Как вы это делали, функция 'handClick' мешала« облачной функции », особенно если у них было разное время. Лучше всего объединить всю логику вместе и весь рендеринг. Оформление должно быть максимально простым, а логика обрабатывает все сложные взаимодействия. – Blindman67

Смежные вопросы