【问题标题】:Why is html canvas animation rendering a temporary gap for each new rectangle?为什么 html 画布动画会为每个新矩形呈现一个临时间隙?
【发布时间】:2019-05-26 19:55:50
【问题描述】:

我有一组在 html5 画布上呈现的矩形或“管道”。新管道在渲染(和动画)之前动态添加到数组中。问题是每个新管道在其自身和前一个管道之间都有一个微小的间隙,一旦引入下一个管道,这个间隙就会消失。任何时候都应该没有间隙。

这太离奇了,快把我逼疯了。

下面的 Codepen 链接应该让这个问题更清楚。

Codepen working example.

const body = document.getElementsByTagName("body")[0];
const canvasWidth = 500;
const canvasHeight = 820;
const canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var frame_count = 0;
var speed = 1;
var pipes = [];

function Pipe(height) {
  this.x = canvasWidth;
  this.height = height;
  this.update = function() {
    ctx.fill();
    ctx.fillStyle = 'black';
    ctx.beginPath();
    ctx.rect(this.x, 0, 100, this.height);
    this.x = this.x - (1 * speed);
  };
}

function setup() {
  // Render blank canvas to dom
  canvas.width = canvasWidth;
  canvas.height = canvasHeight;
  body.appendChild(canvas);
}

function draw() {
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Pipe generator
  if (frame_count % 100 === 0) {
    if (frame_count % 200 === 0) {
      pipes.push(new Pipe(100));
    } else {
      pipes.push(new Pipe(120));
    }
  }

  // Draw pipes
  for (i = 0; i < pipes.length; i++) {
    pipes[i].update();
  }

}

function loop() {
  setTimeout(function() {
    draw();
    frame_count++;
    requestAnimationFrame(loop);
  }, 0);
}

setup();
loop();

【问题讨论】:

    标签: javascript html animation canvas html5-canvas


    【解决方案1】:

    发生这种情况是因为在您的绘图功能中,您所做的一切都是相反的;-)

    目前您首先填充当前路径,然后声明它,最后更新位置。您需要完全相反,这样您才能填充最新版本的绘图,而不是等待一帧。

    当绘制多个形状时,它似乎得到修复,因为在同一帧中,下一个形状正在绘制前一个形状的当前状态。

    const body = document.getElementsByTagName("body")[0];
    const canvasWidth = 500;
    const canvasHeight = 820;
    const canvas = document.createElement('canvas');
    var ctx = canvas.getContext("2d");
    var frame_count = 0;
    var speed = 1;
    var pipes = [];
    
    function Pipe(height) {
      this.x = canvasWidth;
      this.height = height;
      this.update = function() {
        // first update position
        this.x = this.x - (1 * speed);
        ctx.fillStyle = 'black';
        // then declare the path
        ctx.beginPath();
        ctx.rect(this.x, 0, 100, this.height);
        // finally draw it
        ctx.fill();
      };
    }
    
    function setup() {
      // Render blank canvas to dom
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      body.appendChild(canvas);
    }
    
    function draw() {
      // Clear canvas
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    
      // Pipe generator
      if (frame_count % 100 === 0) {
        if (frame_count % 200 === 0) {
          pipes.push(new Pipe(100));
        } else {
          pipes.push(new Pipe(120));
        }
      }
    
      // Draw pipes
      for (i = 0; i < pipes.length; i++) {
        pipes[i].update();
      }
    
    }
    
    function loop() {
    // do not mix setTimeout and rAF, it's like having a Ferrari parked in a truck...
    //  setTimeout(function() {
        draw();
        frame_count++;
        requestAnimationFrame(loop);
    //  }, 0);
    }
    
    setup();
    loop();

    【讨论】:

    • 感谢 setTimeout 说明 :)。我是 js 新手(和一般编程),并且从其他地方粘贴了这个循环函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    相关资源
    最近更新 更多