HTML5画布,图像上/中的多边形可能吗?

时间:2012-05-19 02:28:27

标签: javascript html5 canvas html5-canvas

有没有办法使用javascript html5画布,有多边形,然后在其中显示图像而不是颜色?

2 个答案:

答案 0 :(得分:5)

经过一些研究,我相信可以通过首先使用您的图像创建一个模式,然后将该模式设置为fillStyle来实现这一点:

var ctx = canvas.getContext("2d");
var pattern = ctx.createPattern(imageObj, "repeat");
ctx.fillStyle = pattern;

然后,只需创建多边形(使用moveTolineTo),然后正常填充它。

来源:this plugin的源代码。免责声明:我自己没有尝试确认有效。

更新:我还在调查您是否可以操纵图像以适应任意多边形。原则上,您可以使用setTransform来执行此操作:

ctx.save();
ctx.setTransform(m11, m12, m21, m22, dx, dy);
ctx.drawImage(imageObj);
ctx.restore();

确定setTransform参数的值(如果可以这样做的话)是棘手的部分。因为我做了任何数学,所以它已经很宽松了,但如果我没记错,这里需要做的是:

(0,0) --- (w,0)       (x1,y1) --- (x2,y2)
  |         |            |           |
  |  Image  |     =>     |  Morphed  |
  |         |            |           |
(0,h) --- (w,h)       (x3,y3) --- (x4,y4)

对于每个点,您将执行以下矩阵操作:

|m11 m21 dx|   |xI|   |xM|
|m12 m22 dy| X |yI| = |yM|
| 0   0   1|   | 1|   | 1|

八个方程,六个变量(记住矩阵元素是变量,其余是常量 - 我们的输入)。可能无法解决。现在只需要推导(或谷歌搜索,或在Math.SE中询问......)并为每个参数实现公式......

更新2:虽然我没有确凿的证据,但我相信用setTransform做你想做的事是不可能的。看看Gimp如何使用其“透视”工具,还需要更改变换矩阵的第三行,以将图像转换为任意多边形。并且Canvas API似乎没有为此提供方法(通常只支持仿射变换:平移,旋转,缩放,剪切或上述组合)。

在2D变换上引用this post

  

CSS3 2D-Transforms只能将块转换为平行四边形。例如,无法将块转换为此形状:   [不规则形状]   为此,必须使用CSS3 3D变换。这就是为什么矩阵构造集只有三个控制点可以拖动,而不是四个。

CSS 3D Transforms的计划,但不仅我不知道支持的范围有多广,我不知道如果canvas元素(带有2d上下文,即 - WebGL是另一个故事)将会支持它。简而言之,我不可能通过我所知道的任何方式做你想做的事。

答案 1 :(得分:3)

您可以使用context.clip()

为图像填充多边形
  //create an image
  var img = new Image();
  img.src = 'imgPath/image.png'

  //draw the image when loaded
  img.onload = function(){
      var ctx = canvas.getContext("2d");
      ctx.save();

      //define the polygon
      ctx.beginPath();
      ctx.moveTo(x1,y1);
      ctx.lineTo(x2,y2);
      ctx.lineTo(x3,y3);
      ctx.closePath();

      //draw the image
      ctx.clip();
      ctx.drawImage(img, leftMostXCoor, highestYCoor, polyWidth, polyHeight);

      //fill and stroke are still available for overlays and borders
      ctx.fill();
      ctx.stroke();

      ctx.restore();
  }