So, here's a tricky trick: you can use the regular drawImage of context2d to draw the texture inside the triangle.
The limitation is that the texture coordinates must be aligned along the axis.
To draw a textured triangle, you must: β’ Calculate the transformation you need to draw the image yourself.
β’ Fix the triangle, as drawImage will draw a quad. β’ drawImage with the correct transformation.
So the idea is to split the quad into two triangles and display both.
But there is another trick: when drawing the lower right triangle, reading the texture should start from the bottom right of the texture, and then move up and to the left. This cannot be done in Firefox, which accepts only positive drawImage arguments. Therefore, I calculate the βmirrorβ of the first point against the other two, and I can draw again in the right direction - clipping will ensure that only the right side is drawn.
fiddle here:
http://jsfiddle.net/gamealchemist/zch3gdrx/

function rasterizeTriangle(v1, v2, v3, mirror) { var fv1 = { x: 0, y: 0, u: 0, v: 0 }; fv1.x = v1.x; fv1.y = v1.y; fv1.u = v1.u; fv1.v = v1.v; ctx.save(); // Clip to draw only the triangle ctx.beginPath(); ctx.moveTo(v1.x, v1.y); ctx.lineTo(v2.x, v2.y); ctx.lineTo(v3.x, v3.y); ctx.clip(); // compute mirror point and flip texture coordinates for lower-right triangle if (mirror) { fv1.x = fv1.x + (v3.x - v1.x) + (v2.x - v1.x); fv1.y = fv1.y + (v3.y - v1.y) + (v2.y - v1.y); fv1.u = v3.u; fv1.v = v2.v; } // var angleX = Math.atan2(v2.y - fv1.y, v2.x - fv1.x); var angleY = Math.atan2(v3.y - fv1.y, v3.x - fv1.x); var scaleX = lengthP(fv1, v2); var scaleY = lengthP(fv1, v3); var cos = Math.cos, sin = Math.sin; // ---------------------------------------- // Transforms // ---------------------------------------- // projection matrix (world relative to center => screen) var transfMatrix = []; transfMatrix[0] = cos(angleX) * scaleX; transfMatrix[1] = sin(angleX) * scaleX; transfMatrix[2] = cos(angleY) * scaleY; transfMatrix[3] = sin(angleY) * scaleY; transfMatrix[4] = fv1.x; transfMatrix[5] = fv1.y; ctx.setTransform.apply(ctx, transfMatrix); // !! draw !! ctx.drawImage(bunny, fv1.u, fv1.v, v2.u - fv1.u, v3.v - fv1.v, 0, 0, 1, 1); // ctx.restore(); };
Edit: I added an @szym comment with its example:
This view looks right. If there are direct lines in the original image, you will see that each triangle is deformed differently (2 different affine transformations, not a perspective transformation).
