2013-06-14 17 views
5

Sto provando a disegnare una linea, collegando due cerchi in SVG. I cerchi sono - insieme ai rettangoli sottostanti incapsulati in elementi di un gruppo SVG(). Questi gruppi sono posizionati con gli attributi transform = "translate (x, y)". Il mio problema è che le coordinate degli elementi all'interno del gruppo sono posizionate relativamente alle origini (coordinate 0,0) dei loro gruppi. Per posizionare una linea soprastante ho bisogno di conoscere le coordinate assolute.Come posso convertire le coordinate SVG (x, y) definite relativamente a un elemento in coordinate/posizione assolute?

ecco il codice utilizzando la D3 libreria javascript:

var body = d3.select("body"); 

var svg = body.append("svg"); 

var group1 = svg.append("g") 
    .attr("transform", "translate(50,50)"); 

var rect1 = group1.append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", 100) 
    .attr("height", 100) 
    .style("fill", 'lightblue'); 

var circ1 = group1.append("svg:circle") 
    .attr("cx", 50) 
    .attr("cy", 50) 
    .attr("r", 10) 
    .style("fill", 'red') 

var group2 = svg.append("g") 
    .attr("transform", "translate(350,50)"); 

var rect2 = group2.append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", 100) 
    .attr("height", 100) 
    .style("fill", 'lightgreen'); 

var circ2 = group2.append("svg:circle") 
    .attr("cx", 50) 
    .attr("cy", 50) 
    .attr("r", 10) 
    .style("fill", 'red'); 

var line = svg.append("svg:line") 
    .attr("x1", parseInt(circ1.attr("cx"))) 
    .attr("y1", parseInt(circ1.attr("cy"))) 
    .attr("x2", parseInt(circ2.attr("cx"))) 
    .attr("y2", parseInt(circ2.attr("cy"))) 
    .attr("stroke", "black"); 

so il motivo per cui la linea non viene visualizzata. So anche che ogni elemento SVG è correlato a una matrice di trasformazione. Non sono sicuro di come accedere alle matrici degli elementi del cerchio e come ottenere le loro coordinate assolute (gli attributi cx/cy). Un'altra possibilità sarebbe quella di ottenere la distanza assoluta dei cerchi.

Ecco un jsfiddle with the above code

+0

Sarà molto più semplice se manterrai gli elementi nello stesso gruppo. –

+1

Sì, lo sarà. Ma poi ho fatto attenzione alla posizione dei cerchi e dei rettangoli manualmente. Questo è il motivo per cui ho deciso di provare l'approccio con più gruppi. – karlitos

risposta

6

penso di essere stato in grado di risolvere il problema io stesso. L'accesso alla matrice di trasformazione potrebbe essere realizzato utilizzando

circ1[0][0].getCTM() 

o utilizzando

circ1[0][0].getScreenCTM() 

Aggiungendo il valore del e attributo al x coordinare e il valore del f attributo allo y coordinata Sono riuscito a ottenere la "posizione assoluta" degli elementi.

jsfiddle aggiornamento è here

temo la mia soluzione non è universalmente valida. Ad esempio, non sono sicuro di cosa accadrà in un caso che userò transform: scale prima del calcolo della posizione?

+0

Mi hai fatto andare nella giusta direzione. Penso che leggere e comprendere il capitolo 7 del documento SVG mi fornirà tutta la storia. Suppongo che il metodo preferito sarebbe utilizzare la matrice di trasformazione e varie cose come moltiplicare la matrice per ottenere ciò che tu (e io) stiamo cercando di fare. – pedz

+1

Penso che sia possibile utilizzare la formula completa per la mappatura di un nuovo sistema di coordinate da qui https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform; absX = a * x + c * y + e absY = b * x + d * y + f (che nel caso di tradurre transform semplificherà la soluzione nella tua risposta attuale) –

+0

A proposito, solo getScreenCTM sembra restituire dati validi per me. La matrice di getCTM non cambia la posizione dopo averla applicata. –

Problemi correlati