如何在 2D canvas 中实现缩放功能?

How can I implement a zoom function in a 2D canvas?

我正在尝试为 JavaScript 中的程序纹理创建一个库,但出于某种原因,我无法真正理解为什么我的缩放功能不起作用。我尝试了很多东西,但我总是得到奇怪的结果,而不是我最初想要达到的结果。基本上,如果我放大噪声纹理,我希望它看起来全是块状的。

我当前的实现:

this.Zoom = function(factor) {
  var imageData, curData, newData,
    zoomFactor = Math.pow(2, factor);

  curData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);    
  newData = ctx.createImageData(curData);

  for (var y = 0; y < ctx.canvas.height; y++) {
    for (var x = 0; x < ctx.canvas.width; x++) {
      var curIndex = y * ctx.canvas.width + x;
      var targetIndex = Math.floor(y / zoomFactor + x / zoomFactor) * 4;

      newData.data[curIndex]     = curData.data[targetIndex];
      newData.data[curIndex + 1] = curData.data[targetIndex + 1];
      newData.data[curIndex + 2] = curData.data[targetIndex + 2];
      newData.data[curIndex + 3] = curData.data[targetIndex + 3];
    }
  }

  ctx.putImageData(newData, 0, 0);

  return this;
}

这是我的 JSFiddle:http://jsfiddle.net/j18eqgrq/

出于某种原因,我得到了这种奇怪的效果,但我无法理解它。我想我搞砸了 targetIndex。

在你的内部 for 循环中,代码应该是:

var curIndex = y * ctx.canvas.width * 4 + x * 4;
var targetIndex = Math.floor(y / zoomFactor) * ctx.canvas.width * 4 + Math.floor(x / zoomFactor) * 4;

你应该在因子4中考虑RGBA,并且缩放图像索引应该通过y * image_width + x

计算

您可以通过将原始 canvas 绘制到具有 9 个参数形式 context.drawImage 的新 canvas 来实现缩放。这种形式需要源矩形和目标矩形。当大小不同时,源会相应地拉伸。

当您还没有绘制任何东西并且想从头开始绘制它时可以使用的另一种方法是使用 context.scale to set a zoom factor and context.translate to set the zoom center.