After some research, I find it possible to do this by first creating a template using your image, and then setting this template to fillStyle
:
var ctx = canvas.getContext("2d"); var pattern = ctx.createPattern(imageObj, "repeat"); ctx.fillStyle = pattern;
Then it's just a matter of creating your polygon (using moveTo
and lineTo
) and then filling it up normally.
Source: this source code plugin . Disclaimer: I have not tried to make sure that it works.
Update: I am still studying whether the image can be manipulated to fit an arbitrary polygon. Basically, you can use setTransform
to do this:
ctx.save(); ctx.setTransform(m11, m12, m21, m22, dx, dy); ctx.drawImage(imageObj); ctx.restore();
Determining setTransform
parameter setTransform
(if at all possible) is the hard part. It was looong, since I did any math, but if I call right here what needs to be done:
(0,0) --- (w,0) (x1,y1) --- (x2,y2) | | | | | Image | => | Morphed | | | | | (0,h) --- (w,h) (x3,y3) --- (x4,y4)
For each point, you perform the following matrix operation:
|m11 m21 dx| |xI| |xM| |m12 m22 dy| X |yI| = |yM| | 0 0 1| | 1| | 1|
Eight equations, six variables (remembering that matrix elements are variables, the rest are constants - our inputs). May be unsolvable. Now it is only a matter of inference (or googling, or a query in Math.SE ...) and the implementation of the formulas for each parameter ...
Update 2: Although I have no convincing evidence of this, I find it impossible to do what you want with setTransform
. Considering how Gimp works with its βpromisingβ tool, you need to change the third row of the transformation matrix in order to transform the image into an arbitrary polygon. And the Canvas API does not seem to provide a means for this (usually only affine transforms are supported: translation, rotation, scale, shift, or a combination above).
Quote this post about two-dimensional transformations:
CSS3 2D-Transforms can only convert blocks to parallelograms. For example, it is not possible to convert a block to this form: [Irregular form] To do this, use 3D3 Transforms CSS3. This is why the Matrix Construction Set has only three control points for movement, not four.
There are plans for CSS 3D Transforms , but not only I donβt know how widely supported this is, I donβt know if the canvas element (with a 2d context, that is - WebGL is another story) will always support it. In short, it is impossible to do what you want by any means that I know of.