0

现在,我有一个 JavaScript 函数,它通过 24x24 网格并在每个位置绘制随机颜色。它在 Chrome 中运行良好,但是在 Firefox 中出现了这种可怕的闪烁。现在,通常它看起来像一个缓冲区会修复它,但是画布实际上是不可见的,我只是将它设置为背景使用canvas.toDataURL();所有方块都更新后将其设置为背景。关于它为什么不起作用的任何想法?

编辑:

这是有问题的代码:

  window.onload=function(){
  var canvas = document.getElementById("background"); //canvas is assigned the ID of background
  var canvasBuffer = canvas;
  var ctx = canvas.getContext('2d');

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


  var fps = 30;
  var ar = 0;
  var ag = 0;
  var ab = 0;
  var br = 0;
  var bg = 0;
  var bb = 0;
  var redmod = .6;
  var greenmod = 1.1;
  var bluemod = 1.2;
  var count = 0;
  var coords = new Array(8);


  //create an 8x8 matrix of value pairs (current value and target value)
  for (var i = 0; i < 24; i++) {
      coords[i] = new Array(8);
      for (var j = 0; j < 24; j++) {
          coords[i][j] = new Array(2);
          coords[i][j][0] = randomColor();
          coords[i][j][1] = randomColor();
          ctx.fillStyle = "#" + coords[i][j][0];        
          ctx.fillRect(i * 20, j * 20, 20, 20);
      }
    }

  function assignToDiv(){ // sets the canvas as the background of two divs
    dataUrl = canvas.toDataURL();
    document.getElementById("intro").style.background='url('+dataUrl+')'
    document.getElementById("nav").style.background='url('+dataUrl+')'
  }

  function animate() {
      setTimeout(function () {
          requestAnimFrame(animate);
          requestAnimFrame(assignToDiv);

          // Drawing code goes here
          // changes the general color over time
          if (count == 256){
              redmod = .4;
              greenmod = .8;
              bluemod = 1;
          }
          else if (count == 512){
              redmod = 1.4;
              greenmod = .8;
              bluemod = .6;
          }
          else if (count == 768){
              redmod = 1.3;
              greenmod = .5;
              bluemod = .6;
          }
          else if (count == 1024){
              redmod = 1.1;
              greenmod = .3;
              bluemod = .5;
          }
          else if (count == 1280){
              redmod = .6;
              greenmod = 1.1;
              bluemod = 1.2;
              count = 0;
          }
          count++;
          //choose 3 squares to change        
          for (var m = 0; m < 3; m++){

              var r = parseInt(Math.random() * 24);
              var c = parseInt(Math.random() * 24);

              coords[c][r][1] = randomColor();
          }
          //update each square
          for (var k = 0; k < 24; k++) {
              for (var l = 0; l < 24; l++) {
                  //make sure all colors are 6 digits long
                  while (coords[k][l][0].length<6){
                      coords[k][l][0]= "0" + coords[k][l][0];
                  }
                  while (coords[k][l][1].length<6){
                      coords[k][l][1]= "0" + coords[k][l][1];
                  }

                  //convert the red, green, and blue values back to dec
                  ar = parseInt(coords[k][l][0].substring(0,2),16);
                  ag = parseInt(coords[k][l][0].substring(2,4),16);
                  ab = parseInt(coords[k][l][0].substring(4,6),16)

                  br = parseInt(coords[k][l][1].substring(0,2),16);
                  bg = parseInt(coords[k][l][1].substring(2,4),16);
                  bb = parseInt(coords[k][l][1].substring(4,6),16);              

                  //move the current color closer to the target color
                  ar = parseInt(ar + (br - ar)/fps);
                  ag = parseInt(ag + (bg - ag)/fps);
                  ab = parseInt(ab + (bb - ab)/fps);
                  //put it pack to hex
                  var RR = ((ar.toString(16).length==1)?"0"+ar.toString(16):ar.toString(16));
                  var GG = ((ag.toString(16).length==1)?"0"+ag.toString(16):ag.toString(16));
                  var BB = ((ab.toString(16).length==1)?"0"+ab.toString(16):ab.toString(16));

                  coords[k][l][0] = RR + GG + BB;

                  ctx.fillStyle = "#" + coords[k][l][0];
                  ctx.fillRect(k * 20, l * 20, 20, 20);
              }
          }


      }, 1000 / fps);
  }

  // create a random color object {red,green,blue}
  function randomColor() {
    var red = Math.floor(Math.random() * 128 * redmod);
    var green = Math.floor(Math.random() * 128 * greenmod);
    var blue = Math.floor(Math.random() * 128 * bluemod);
    var avg = red * .3 + green * .6 + blue * .1;

    red = parseInt(red * .5 + avg * .5);
    green = parseInt(green * .5 + avg * .5);
    blue = parseInt(blue * .5 + avg * .5);

      var redhex = ((red.toString(16).length==1)?"0"+red.toString(16):red.toString(16));
      var greenhex = ((green.toString(16).length==1)?"0"+green.toString(16):green.toString(16));
      var bluehex = ((blue.toString(16).length==1)?"0"+blue.toString(16):blue.toString(16));

      return (redhex + greenhex + bluehex);
  }


  animate();
  assignToDiv();

  }  

然后将画布放在 body 的顶部:

    <canvas id="background" width=480 height=480></canvas>

在 CSS 中:

#background {
display:none;
}
4

1 回答 1

1

您的问题是您要以 60fps 的速度替换 2 个元素背景。

与其不断替换“intro”和“nav”的背景,不如在 intro 和 nav 下叠加一个画布元素。然后在那些底层画布上绘制。

于 2013-10-15T04:04:14.423 回答