Quindi, ecco un trucco uccisione: È possibile utilizzare la drawImage regolare del context2d per disegnare una texture all'interno di un triangolo.
Il vincolo è che le coordinate della trama devono essere allineate all'asse.
Per disegnare un triangolo con texture è necessario:
• Calcola da solo la trasformazione richiesta per disegnare l'immagine.
• Agganciare a un triangolo, poiché drawImage disegnerebbe un quad.
• drawImage con la trasformazione corretta.
Quindi l'idea è di dividere il quad in due triangoli e renderli entrambi.
Ma c'è un altro trucco: quando si disegna il triangolo in basso a destra, la lettura della trama dovrebbe iniziare dalla parte in basso a destra della trama, quindi spostarsi verso l'alto e verso sinistra. Questo non può essere fatto in Firefox, che accetta solo argomenti positivi per disegnareImmagine. Quindi computo lo "specchio" del primo punto rispetto agli altri due, e posso ancora disegnare nella direzione normale: il ritaglio garantirà che venga disegnata solo la parte destra.
violino è qui:
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: ho aggiunto il relativo commento di @szym, con il suo esempio d'immagine:
questo solo tipo di sembra giusto. Se ci sono linee rette nell'immagine originale vedrai che ogni triangolo è deformato in modo diverso (2 diverse trasformazioni affini piuttosto che una trasformazione prospettiva).
Sto pensando la risposta migliore sarebbe quella di utilizzare WebGL che fornisce funzionalità 3D sulla tela, ma se non voglio provare che si potrebbe anche sguardi nella manipolazione delle immagini – Canvas
Can voi usare qualcosa di diverso dalla tela es css3 trasformare? – soktinpk
Vuoi fornire l'immagine modificata al tuo utente? – GameAlchemist