首页 > 解决方案 > 画布在第一次绘制时无法正确绘制图像

问题描述

我在 Chrome 中使用 HTML5 Canvas 时遇到了奇怪的行为。如下例所示,在调整窗口大小之前,图像无法正确呈现。所有变量和属性在初始和调整大小时都具有完全相同的值。为什么会这样?

当然,如果图像尚未加载,则根本不会显示背景。您可能需要刷新几次。

<html>
<head>
</head>
<body>
<canvas id="test-canvas"></canvas>
</body>
<script>
    var canvas = document.querySelector('#test-canvas');
    var backgroundImage = new Image(100, 100);

    backgroundImage.src = 'https://via.placeholder.com/100';

    var dimensions = [];
    var center = [];
    var viewBox = [];

    function paint() {
      var ctx = canvas.getContext('2d');

      dimensions = [canvas.width, canvas.height];
      center = [dimensions[0] / 2, dimensions[1] / 2];
      viewBox = [
        -center[0], -center[1],
        center[0], center[1],
      ];

      ctx.translate(center[0], center[1]);

      paintBackground(ctx);
    }

    function paintBackground(ctx) {
      ctx.save();

      var size = [100, 100]

      var box = [
        Math.floor(viewBox[0] / size[0]) * size[0],
        Math.floor(viewBox[1] / size[1]) * size[1],
        Math.ceil(viewBox[2] / size[0]) * size[0],
        Math.ceil(viewBox[3] / size[1]) * size[1],
      ];

      for (let x = box[0]; x < box[2]; x += size[0]) {
        for (let y = box[1]; y < box[3]; y += size[1]) {
          ctx.drawImage(backgroundImage, x, y, size[0], size[1]);
        }
      }

      ctx.restore();
    }

    function resize() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        paint();
    }

    window.addEventListener('resize', resize);
    resize();

    setTimeout(paint, 200); 

</script>
</html>

图像应该覆盖整个画布......

在此处输入图像描述

但最初它们只覆盖右下象限......

在此处输入图像描述

标签: html5-canvas

解决方案


我想到了。我每次画画都在翻译。我意识到我需要对我的save方法进行调用。这解决了我的问题。restorepaint

function paint() {
  var ctx = canvas.getContext('2d');
  ctx.save() // <--- here!

  dimensions = [canvas.width, canvas.height];
  center = [dimensions[0] / 2, dimensions[1] / 2];
  viewBox = [
    -center[0], -center[1],
    center[0], center[1],
  ];

  ctx.translate(center[0], center[1]);

  paintBackground(ctx);

  ctx.restore() // <--- and here!
}

推荐阅读