简体   繁体   English

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

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

I'm trying to create a library for procedural textures in JavaScript and for some reason I can't really wrap my head around why my zooming function wont work. 我正在尝试为JavaScript中的过程纹理创建一个库,由于某种原因,我无法真正解决为什么缩放功能无法正常工作的问题。 I tried lots of things but I always get funky results instead of what I originally wanted to achieve. 我尝试了很多事情,但总是得到时髦的结果,而不是我最初想要实现的结果。 Basically, if I zoom into a noise texture I want it to appear all blocky. 基本上,如果我放大噪点纹理,我希望它看起来全部是块状的。

My current implementation: 我当前的实现:

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;
}

And here's my JSFiddle: http://jsfiddle.net/j18eqgrq/ 这是我的JSFiddle: http : //jsfiddle.net/j18eqgrq/

For some reason I get this weird effect and I can't wrap my head around it. 由于某种原因,我得到了这种怪异的效果,我无法解决这个问题。 I think I messed up something with the targetIndex. 我想我把targetIndex弄乱了。

In your inner for-loop the code should be: 在您的内部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;

You should take the RGBA into account in the factor 4, and also the zoomed image index should be calculated through y * image_width + x 您应该将RGBA纳入因子4中,并且缩放的图像索引应通过y * image_width + x进行计算

You can implement zooming by taking the original canvas and drawing it to a new canvas with the 9-argument form of context.drawImage . 您可以通过采用原始画布并将其绘制为带有9个参数的context.drawImage的新画布来实现缩放。 This form requires both a source- and a target-rectangle. 这种形式需要源矩形和目标矩形。 When the sizes differ, the source is stretched accordingly. 当大小不同时,源将相应地拉伸。

Another method you can use when you haven't drawn anything yet and you want to draw it zommed from the start is to use context.scale to set a zoom factor and context.translate to set the zoom center . 当您还没有绘制任何东西并且想要从一开始就对其进行缩放时,可以使用的另一种方法是使用context.scale设置缩放因子,并使用context.translate设置缩放中心

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM