在2D画布中,有没有办法给精灵一个轮廓?

时间:2014-08-23 23:46:00

标签: javascript html5 canvas

当角色被痊愈/受损/其他什么时,我想给精灵一个大纲,但我想不出用二维画布编码的方法。如果有可能,我认为这将是global composite operation,但我无法想到用其中一个实现它的方法。

我确实发现这个stackoverflow answer建议创建一个更丰富的纯色版本的原件并将原件放在它上面。这会给它一个轮廓,但它似乎是很多额外的工作,特别是考虑到我使用占位符艺术。有没有更简单的方法?

这个问题与链接的问题不同,因为这是关于HTML5 2D画布的。它可能有其他问题无法解决的问题。

对于它的价值,我不介意如果轮廓创建一个更宽的边框或保持精灵相同的大小,我只想要轮廓外观。

3 个答案:

答案 0 :(得分:4)

  • 只需将原始图像绘制在原始图像周围的8个位置
  • 将复合模式更改为source-in并填充轮廓颜色
  • 将复合模式更改回source-over并在正确位置绘制原始图像

这将创建一个干净锐利的轮廓,每边都有相同的边框粗细。然而,它不适合厚实的轮廓。图像绘制很快,特别是当图像没有缩放时,性能不是问题,除非您需要绘制一堆(在这种情况下,您将缓存图纸或使用精灵表格)。

示例:



var ctx = canvas.getContext('2d'),
    img = new Image;

img.onload = draw;
img.src = "http://i.stack.imgur.com/UFBxY.png";

function draw() {

  var dArr = [-1,-1, 0,-1, 1,-1, -1,0, 1,0, -1,1, 0,1, 1,1], // offset array
      s = 2,  // scale
      i = 0,  // iterator
      x = 5,  // final position
      y = 5;
  
  // draw images at offsets from the array scaled by s
  for(; i < dArr.length; i += 2)
    ctx.drawImage(img, x + dArr[i]*s, y + dArr[i+1]*s);
  
  // fill with color
  ctx.globalCompositeOperation = "source-in";
  ctx.fillStyle = "red";
  ctx.fillRect(0,0,canvas.width, canvas.height);
  
  // draw original image in normal mode
  ctx.globalCompositeOperation = "source-over";
  ctx.drawImage(img, x, y);
}
&#13;
<canvas id=canvas width=500 height=500></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

也许值得尝试一下:

•构建一个比原始精灵大1.1倍的画布   •用轮廓颜色填充
  •使用destination-in globalCompositeOperation在画布上绘制缩放1.1的精灵。

然后你的轮廓颜色的精灵有一个更大的'阴影'。

当你想绘制轮廓时:

•绘制'阴影'(居中)
   •在阴影中绘制精灵。

根据精灵的凸度,这或多或少都会很好用,但我认为值得尝试,因为它避免了你输入图形文件的数量增加一倍。

我只是做了一个简短的尝试作为概念验证,它很有效:
http://jsbin.com/dogoroxelupo/1/edit?js,output

之前: enter image description here

之后:enter image description here

HTML

<html>
<body>
  <image src='http://www.gifwave.com/media/463554/cartoons-comics-video-games-sprites-scott-pilgrim-paul-robertson_200s.gif' id='spr'></image>
  <canvas id='cv' width = 500 height= 500 ></canvas>
</body>
</html>

代码

window.onload=function() {
  var spr = document.getElementById('spr');
  var margin = 4;
  var gh = createGhost(spr, '#F80', margin);
  var cv = document.getElementById('cv');
  var ctx = cv.getContext('2d');
  var outlined = true;
  setInterval(function() {
     ctx.clearRect(0,0,cv.width, cv.height);
     if (outlined)       
       ctx.drawImage(gh, 0, 0)
     ctx.drawImage(spr, 0, 0)
     outlined = !outlined;
  }, 400);
}

function createGhost (img, color, margin) {
  var cv= document.createElement('canvas');
  cv.width = img.width+2*margin;
  cv.height = img.height + 2*margin;
  var ctx = cv.getContext('2d');
  ctx.fillStyle = color;
  ctx.fillRect(0,0, cv.width, cv.height);
  ctx.save();
  ctx.globalCompositeOperation = 'destination-in';
  var scale = cv.width/spr.width;
  ctx.scale(cv.width/spr.width, cv.height/spr.height); 
  ctx.drawImage(img, -margin, -margin);
  ctx.restore();
  return cv;  
}

答案 2 :(得分:-1)

绘制后可以使用strokeRect方法勾画精灵。如果你知道你的精灵维度,那应该是很好的......