HTML5 Canvas闪烁,不要认为缓冲区会起作用

HTML5 Canvas flickering, don't think a buffer will work

本文关键字:缓冲区 起作用 Canvas 闪烁 HTML5      更新时间:2023-09-26

现在,我有一个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();
  }  

然后将画布放置在正文的顶部:

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

在 CSS 中:

#background {
display:none;
}

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

与其不断替换"介绍"和

"导航"的背景,不如在介绍和导航下分层画布元素。然后在这些底层画布上绘画。