2013-03-27 3 views
25

Sto provando a mappare un'immagine a una griglia "3D" che simula la stoffa usando strokeStyle e canvas, ho incluso l'immagine ma al momento agisce come un'immagine di sfondo e non scorre effettivamente con il "panno" come le increspature, IE l'immagine è statica mentre la griglia scorre. questo è il jsfiddle che è autoesplicativo (funziona solo in Chrome). qualsiasi aiuto è molto apprezzato. Ecco il javascript che rende l'immagine in secondo piano, Come faccio a smettere dal rendering come immagine di sfondo e solo rendere riempire la griglia ?:html5 canvas strokeStyle?

function update() { 

    var img = new Image(); 
    img.src = 'http://free-textures.got3d.com/architectural/free-stone-wall- textures/images/free-stone-wall-texture-002.jpg'; 
    img.onload = function() { 

     // create pattern 
     var ptrn = ctx.createPattern(img, 'repeat'); 

     ctx.clearRect(0, 0, canvas.width, canvas.height); 

     physics.update(); 

     ctx.strokeStyle = ptrn; 
     ctx.beginPath(); 
     var i = points.length; 
     while (i--) points[i].draw(); 
     ctx.stroke(); 

     requestAnimFrame(update); 
    } 
} 

La sua è l'originale codepen sto lavorando da. `aggiornato fiddle con l'aggiornamento dell'immagine esterna funzione(): Attualmente sembra riempire effettivamente le celle e applicarlo come immagine di sfondo. c'è un modo per impedirlo di diventare un'immagine di sfondo e applicarlo solo per riempire la griglia? Ho provato questo:
ctx.fillStyle = ptrn; e rimozione linea 260:
ctx.strokeStyle = ptrn; ma sembra rimuovere l'immagine di sfondo semplicemente mostrandola come una griglia nera ... grazie ancora per la pazienza

+0

no Non mi aspetto che qualcuno esegua il debug del muro di codice la mia domanda esatta è: Come mappare l'immagine alla griglia, funzione update() { var img = new Image(); img.src = 'file: /// C: /Users/CL%20Ceintuurbaan/Desktop/texture_2.jpg'; img.onload = function() { // crea pattern var ptrn = ctx.createPattern (img, 'repeat'); \t ctx.clearRect (0, 0, canvas.width, canvas.height); \t physics.update(); \t ctx.strokeStyle = ptrn; \t ctx.beginPath(); \t var i = points.length; \t mentre (i--) punti [i] .draw(); \t ctx.stroke(); \t requestAnimFrame (aggiornamento); } } È la funzione che riguarda il rendering dell'immagine. – vimes1984

+0

fammi modificare la domanda scusa per l'inconvertenza. – vimes1984

+0

OK, ho capito. Ma temo che dovrai fare un 'drawImage' per cella del tuo muro. –

risposta

33

Oh mio! Ottima domanda!

Quindi vediamo cosa abbiamo. Un sistema che ha un sacco di "vincoli", che sono insiemi di 2 punti. Gli stessi contrattempi vengono a coppie e formano due linee, formando una forma (in basso a destra di una finestra).

Se dovessimo disegnare ogni linea vincolo individualmente ci piacerebbe vedere questo:

boxes!

Ecco tutte le linee rosse orizzontali e linee verticali blu. Disegnando uno solo vedremmo quella forma , e ogni lunga linea rossa è in realtà centinaia di piccole righe, la parte inferiore di ogni forma , end to end. Qui ci sono diverse centinaia di e insieme lo fanno sembrare una mesh coesiva. Il fatto che ognuno sia già individuale rende questo facile per noi.

Questa forma è tutto ciò che serve per determinare una sorta di riquadro di delimitazione. E sembra che ogni Point in un Constraint abbia valori originali, quindi li salveremo come sx e sy.

Se conosciamo i limiti delle caselle nella loro nuova posizione e conosciamo i limiti originali perché abbiamo salvato tutti i valori del Punto per i Contraenti, allora dovremmo essere d'oro.

Una volta che abbiamo il rettangolo di selezione originale di un vincolo e la sua attuale rettangolo di selezione, perché, tutto quello che dobbiamo fare è chiamata drawImage con entrambe le caselle: ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);

ho scritto un nuovo Constraint.prototype.draw di routine, sembra che questo :

yeah!

more yeah!

E così via.

Ci sono alcuni modi in cui è possibile "patchare" i buchi, e dipende da te, altrimenti dovrai finire con le trasformazioni.

Dai un'occhiata al codice. Non ho cambiato molto. Cerca !!! nel codice (le mie modifiche) e DEBUG: nel codice (codice di debug nel caso in cui l'immagine non viene caricata o vuoi vedere i wireframe).

http://jsfiddle.net/simonsarris/Kuw6P/

Il codice è lungo quindi non voglio incollare tutto qui, ma qui è una copia di backup nel caso in cui jsfiddle va giù: https://gist.github.com/simonsarris/5405304

Ed ecco la parte più rilevante:

// !!! new super awesome draw routine! So cool we skipped naming it draw2! 
Constraint.prototype.draw3 = function(otherP2) { 

    // NOW dear friends consider what we have. Each box is made out of two lines, 
    // the bottom and rightmost ones. 
    // From these lines we can deduce the topleft and bottom-right points 
    // From these points we can deduce rectangles 
    // From the skewed rectangle vs the original rectangle we can "stretch" 
    // an image, using drawImage's overloaded goodness. 

    // AND WE'RE OFF: 

    // destination rect has 2 points: 
    //top left: Math.min(this.p2.x, otherP2.x), Math.min(this.p2.y, otherP2.y) 
    //bottom right: (this.p1.x, this.p1.y) 

    // image destination rectangle, a rect made from the two points 
    var dx = Math.min(this.p1.x, Math.min(this.p2.x, otherP2.x)); 
    var dy = Math.min(this.p1.y, Math.min(this.p2.y, otherP2.y)); 
    var dw = Math.abs(this.p1.x - Math.min(this.p2.x, otherP2.x)); 
    var dh = Math.abs(this.p1.y - Math.min(this.p2.y, otherP2.y)); 
    // DEBUG: IF THERE IS NO IMAGE TURN THIS ON: 
    //ctx.strokeStyle = 'lime'; 
    //ctx.strokeRect(dx, dy, dw, dh); 

    // source rect 2 points: 
    //top left: Math.min(this.p2.sx, otherP2.sx), Math.min(this.p2.sy, otherP2.sy) 
    //bottom right: (this.p1.sx, this.p1.sy) 

    // these do NOT need to be caluclated every time, 
    // they never change for a given constraint 
    // calculate them the first time only. I could do this earlier but I'm lazy 
    // and its past midnight. See also: http://www.youtube.com/watch?v=FwaQxDkpcHY#t=64s 
    if (this.sx === undefined) { 
    this.sx = Math.min(this.p1.sx, Math.min(this.p2.sx, otherP2.sx)); 
    this.sy = Math.min(this.p1.sy, Math.min(this.p2.sy, otherP2.sy)); 
    this.sw = Math.abs(this.p1.sx - Math.min(this.p2.sx, otherP2.sx)); 
    this.sh = Math.abs(this.p1.sy - Math.min(this.p2.sy, otherP2.sy)); 
    } 
    var sx = this.sx; 
    var sy = this.sy; 
    var sw = this.sw; 
    var sh = this.sh; 
    // DEBUG: IF THERE IS NO IMAGE TURN THIS ON: 
    //ctx.strokeStyle = 'red'; 
    //ctx.strokeRect(sx, sy, sw, sh); 


    // IF we have a source and destination rectangle, then we can map an image 
    // piece using drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) 
    // Only problem, we're not exactly dealing with rectangles.... 
    // But we'll deal. Transformations have kooties anyways. 
    ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh); 
};