HTML5 Canvas drawImage调整大小问题

时间:2016-01-01 15:29:40

标签: javascript html5 canvas drawimage

当我调整使用drawImage从spritesheet上的特定位置拉出的图像时,看起来好像drawImage有时会拉到源x +源y / swidth + sheight边界之外。

以下jfiddle说明了正在发生的事情:https://jsfiddle.net/cxuxyLj2/

相关代码如下:

drawingSurface.drawImage(heroSprite, 0, 64, 32, 64, 20, 144, 32, 64);
drawingSurface.drawImage(heroSprite, 0, 64, 32, 64, 20+50, 144, 32*2, 64*2);

有一些线条显示在RESIZED精灵的头部上方(可能在第一排拉动相同角色的鞋子),但不是原始精灵的头部。

我的问题是 - 可以确认这是一个合法的drawImage错误,还是我做错了什么?

1 个答案:

答案 0 :(得分:1)

这实际上是因为重新调整你的精灵时的反别名 因为你确实在循环中绘制,而没有清除上下文,所以反别名工件变得越来越大:

var canvas = document.querySelector("canvas");
var drawingSurface = canvas.getContext("2d");

var heroSprite = new Image();

heroSprite.src = "http://gopus.xepher.net/game/gfx/herosprite7.png";

render();

function render () {
	setTimeout(render, 1000);
	drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20, 25, 32, 64);
	drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20+50, 25, 32*2, 64*2);
	drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 150.6666687774, 25.33333222227, 32,64);
}
<canvas width="400" height="400" style="border:1px solid #000"></canvas>

您可以通过将imageSmoothingEnabled标志设置为false来避免它,但在10之前的IE中不支持它...

var canvas = document.querySelector("canvas");
var drawingSurface = canvas.getContext("2d");

drawingSurface.mozImageSmoothingEnabled = false;
drawingSurface.webkitImageSmoothingEnabled = false;
drawingSurface.msImageSmoothingEnabled = false;
drawingSurface.imageSmoothingEnabled = false;

var heroSprite = new Image();

heroSprite.src = "http://gopus.xepher.net/game/gfx/herosprite7.png";

render();

function render() {
  setTimeout(render, 16);

  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20, 25, 32, 64);
  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20 + 50, 25, 32 * 2, 64 * 2);
  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 150.6666687774, 25.33333222227, 32, 64);
}
<canvas width="400" height="400" style="border:1px solid #000"></canvas>

...或者通过在每次调用时清除画布,你可以避免文物增长,但仍然会有自然的......

var canvas = document.querySelector("canvas");
var drawingSurface = canvas.getContext("2d");

var heroSprite = new Image();

heroSprite.src = "http://gopus.xepher.net/game/gfx/herosprite7.png";

render();

function render() {
  setTimeout(render, 16);

  drawingSurface.clearRect(0,0,canvas.width, canvas.height);
  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20, 25, 32, 64);
  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 20 + 50, 25, 32 * 2, 64 * 2);
  drawingSurface.drawImage(heroSprite, 0, 32, 32, 64, 150.6666687774, 25.33333222227, 32, 64);
}
<canvas width="400" height="400" style="border:1px solid #000"></canvas>

...所以最终的解决方案是使用缓冲画布,只能以正常比例绘制精灵(尽可能减少抗锯齿),然后重绘 这个需要比例的缓冲画布,你将保留图像中的抗锯齿效果,但不会再吃掉裁剪区域的边框:

var canvas = document.querySelector("canvas");
var drawingSurface = canvas.getContext("2d");

var heroSprite = new Image();

heroSprite.src = "http://gopus.xepher.net/game/gfx/herosprite7.png";

var spriteCanvas = document.createElement('canvas');
var spriteCtx = spriteCanvas.getContext('2d');

var croppedSprite = function(x, y, width, height){
  spriteCanvas.width = width;
  spriteCanvas.height = height;
  spriteCtx.drawImage(heroSprite, x, y, width, height, 0,0, width, height);
  return spriteCanvas;
  }

render();

function render() {
  setTimeout(render, 16);

  drawingSurface.drawImage(croppedSprite(0, 64, 32, 64), 20, 25, 32, 64);
  drawingSurface.drawImage(croppedSprite(0, 64, 32, 64), 20 + 50, 25, 32 * 2, 64 * 2);
  drawingSurface.drawImage(croppedSprite(0, 64, 32, 64), 150.6666687774, 25.33333222227, 32, 64);
}
<canvas width="400" height="400" style="border:1px solid #000"></canvas>

此外,你绝对应该在精灵之间添加更多空间。