2010-08-07 7 views
15

di Webkit rispetto allo scorso anno sulla 3D transforms spiega le varie trasformare 'funzioni' che possono essere utilizzati nella proprietà -webkit-trasformare. Ad esempio:Come leggere i singoli valori di trasformazione in JavaScript? post sul blog

La mia domanda: come si accede ai singoli valori in JavaScript? Quando si legge la proprietà webkitTransform dell'elemento, basta avere una funzione Matrix3D() con 16 valori in essa, come questo ...

matrix3d(0.958684, 0.000000, .....) 

c'è un modo di leggere solo il valore di un individuo di trasformare cosa , come ruotare Y()? O devo leggerlo dalla stringa matrix3d ​​() e come?

risposta

2

Questo link from Apple Dev Reference potrebbe far luce sull'argomento:

La struttura webkitTransform è una rappresentazione stringa di un elenco di trasformazione operazioni. Solitamente questo elenco contiene un'unica matrice operazione di trasformazione. Per le trasformazioni 3D , il valore è "matrice3d (...)" con i 16 valori di matrice 4x4 omogenea tra parentesi . Per 2D trasforma, il valore è una "matrice (...)" stringa contenente i valori vettoriali 6.

1

Poiché si ottiene solo il valore di matrice finale dallo stile calcolato, potrebbe essere necessario controllare le regole di stile in linea o foglio di stile dell'elemento. Se element.style.webkitTransform ti dà nulla, si potrebbe per scorrere i fogli di stile del documento, e vedere uno che abbina il vostro elemento. Quindi è possibile regex la proprietà webkitTransform per ottenere/impostare il valore.

0

ho pensato a una possibilità. Se siete pronti per analizzare le stringhe in JavaScript, utilizzare

data=document.getElementById("myDiv").getAttribute("-webkit-transform");

quindi interpretare data.

+3

-webkit-trasformazione non è un attributo, quindi non è possibile accedervi tramite l'attributo, si dovrebbe accedere stile oggetto associato all'elemento. – shabunc

3

penso, come syockit dice, scorrendo i fogli di stile è l'unico modo per andare, è possibile utilizzare webkitMatchesSelector per scoprire le regole che corrispondono alla vostra elemento:

var theRules = new Array(); 
var theStylesheet = document.styleSheets; 
if (document.styleSheets[0].cssRules) 
     theRules = document.styleSheets[0].cssRules 
else if (document.styleSheets[0].rules) 
     theRules = document.styleSheets[0].rules 

var elem = document.getElementById("myDiv"); 

for (var i=0; i < theRules.length; i++) { 
    if (elem.webkitMatchesSelector(theRules[i].selectorText)) { 
     var theStyles = theRules[i].style; 
     var j = theStyles.cssText.indexOf('-webkit-transform:'); 
     if (j>-1) { 
      var s = theStyles.cssText.substring(j,theStyles.cssText.length).indexOf(';'); 
      document.getElementById("output").innerHTML=theStyles.cssText.substring(j+18,s); 
     } 
    } 
} 

Ciò presuppone marcatura qualcosa di simile, ho aggiunto alcune regole e valori aggiuntivi per assicurarsi che stavo tirando fuori i valori giusti. Se si dispone di più di un foglio di stile allora avete bisogno di regolare la prima parte per scorrere tutti i fogli di stile anche, e probabilmente avere a che fare con la specificità se il -webkit-transform appare in più di una regola:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>Get style</title> 
    <style> 
    div { 
     margin: 2em; 
     padding: 2em; 
    } 
    #myDiv { 
     -webkit-transform: scale(1.1) rotateY(7deg) translateZ(-1px); 
     border: 1px solid; 
    } 
    </style> 
</head> 
<body> 
    <div id="myDiv"> 
     Just testing. 
    </div> 
    <div id="output"> 
    </div> 
</body> 
</html> 
+0

+1 Ottima risposta, anche se funziona solo per gli stili in linea CSS –

+0

Intendevo "anche se funziona solo per i fogli interni" –

+0

Ho aggiunto il tuo codice su fiddle e non posso ottenere alcuna lettura http://jsfiddle.net/ypf2wv4g/9/ – thednp

3

Mi sono imbattuto in questo problema stamattina. Sembra che JavaScript non è in grado di leggere la proprietà di un elemento style.webkitTransform fino a quando è stato impostato in modo esplicito nel attributo style dell'elemento (sia in linea in HTML o procedurale tramite JavaScript). Per quanto possa sembrare azzardato, se hai bisogno di JS per poter leggere le proprietà di trasformazione CSS, è meglio definire i loro valori iniziali con JavaScript quando il DOM è pronto.

esempio, utilizzando jQuery:

$(document).ready(function(){ 
    $('.transform').css('webkitTransform', 'translateX(0)'); 
}); 

Da questo punto in avanti, sarete in grado di leggere dell'elemento trasformare corda e analizzare attraverso di essa per i valori necessari.

12
// Suppose the transformed element is called "cover". 
var element = document.getElementById('cover'); 
computedStyle = window.getComputedStyle(element, null); // "null" means this is not a pesudo style. 
// You can retrieve the CSS3 matrix string by the following method. 
var matrix = computedStyle.getPropertyValue('transform') 
    || computedStyle.getPropertyValue('-moz-transform') 
    || computedStyle.getPropertyValue('-webkit-transform') 
    || computedStyle.getPropertyValue('-ms-transform') 
    || computedStyle.getPropertyValue('-o-transform'); 

// Parse this string to obtain different attributes of the matrix. 
// This regexp matches anything looks like this: anything(1, 2, 3, 4, 5, 6); 
// Hence it matches both matrix strings: 
// 2d: matrix(1,2,3,4,5,6) 
// 3d: matrix3d(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); 
var matrixPattern = /^\w*\((((\d+)|(\d*\.\d+)),\s*)*((\d+)|(\d*\.\d+))\)/i; 
var matrixValue = []; 
if (matrixPattern.test(matrix)) { // When it satisfy the pattern. 
    var matrixCopy = matrix.replace(/^\w*\(/, '').replace(')', ''); 
    console.log(matrixCopy); 
    matrixValue = matrixCopy.split(/\s*,\s*/); 
} 

Spero che questo aiuti! Si noti che non ho usato un'altra libreria tranne l'API DOM semplice e la funzione RegExp Javascript nativa. Quindi, dovrebbe funzionare universalmente su browser e applicazioni.

+0

Sebbene questo divida ogni valore di matrice in un array, i valori non rappresentano le proprietà di trasformazione CSS e pertanto non rispondono alla domanda dell'OP. –

1

è possibile utilizzare regex per ottenere una mappa della proprietà-valore:

se transformstyle variabile contiene il valore dello stile

//get all transform declarations 
(transformstyle.match(/([\w]+)\(([^\)]+)\)/g)||[]) 
     //make pairs of prop and value   
    .map(function(it){return it.replace(/\)$/,"").split(/\(/)}) 
    //convert to key-value map/object   
    .reduce(function(m,it){return m[it[0]]=it[1],m},{}) 

per:

var transformstyle="-webkit-transform: scale(1.1) rotateY(7deg) translateZ(-1px)" 

otterresti:

{scale: "1.1", rotateY: "7deg", translateZ: "-1px"} 
+0

È sorprendente che una funzione così eccezionale non abbia un'API javascript più potente. In realtà, i singoli valori devono essere analizzati usando regex? Blech. – freakTheMighty

+0

No! Lo standard js getComputedStyle restituisce una matrice/matrice3d. Quindi, è necessario analizzare e calcolare i dati matrix per ottenere le trasformazioni css. – Jordan

+1

Sebbene questo divida ogni valore di matrice in un array, i valori non rappresentano le proprietà di trasformazione CSS e pertanto non rispondono alla domanda dell'OP. –

1

Solo perché mi hanno ragione't vedere alcun Javascript uno soluzioni di linea di lavoro per convertire il codice a matrice, qui è mio. Facile e veloce:

prima ottenere tutti i valori trasformare in una matrice:

var yourDivsCssValues= window.getComputedStyle(yourDiv, null); 
transformValues = testDivCSS.getPropertyValue('transform'); 

Per estrarre trasformare-y come un numero intero:

var transformValueY = parseInt((yourVariable1.replace (/,/g, "")).split(" ")[5]); 

Per estrarre trasformare-x come un numero intero:

var transformValuetX = parseInt((yourVariable2.replace (/,/g, "")).split(" ")[4]); 

L'accesso al valore di rotazione è abbastanza difficile, ma c'è una buona guida, se si desidera t o Fallo: https://css-tricks.com/get-value-of-css-rotation-through-javascript/

3

Vecchia ma interessante domanda e nessuna risposta precedente ha tentato di rispondere.

Sfortunatamente non esiste una soluzione a due linee per il caso generale e non sappiamo quale varietà di passaggi di trasformazione (ruotare, tradurre ecc.) Debba essere decodificata; meno è facile.

Negli ultimi browser basati su WebKit, si può semplicemente interrogare la proprietà precedentemente assegnato:

var element = document.querySelector('div.slipping'); 
element.style.webkitTransform 
    -> "translate(-464px, 0px)" 

Continuiamo con il presupposto che lo stile calcolata deve essere utilizzato. L'esigenza sorge, ad esempio, se l'elemento si trova nel mezzo di una transizione CSS o di un'animazione CSS, vale a dire che la trasformazione corrente non è quella che è stata impostata direttamente.

La stringa del descrittore di matrice restituita da getComputedStyle può infatti essere analizzata tramite un'espressione regolare, ma non tutte le versioni precedenti sono affidabili e sono troppo opache.Un modo semplice per abbattere la stringa, se non è in un ciclo molto stretto da giustificare una regex single-pass, è questa:

var matrixString = window.getComputedStyle(element).webkitTransform; 
var matrix = matrixString 
      .split('(')[1] 
      .split(')')[0] 
      .split(',') 
      .map(parseFloat); 

Ma un altro modo è quello di usare semplicemente questo, che non è stato detto prima:

var cssMatrix = new WebKitCSSMatrix(matrixString); 

il vantaggio di quest'ultimo approccio è che si ottiene indietro una matrice 4x4 pure, che è la rappresentazione standard per affine transformations, e lo svantaggio è che è naturalmente WebKit specifico. Se continui a lavorare con la tupla di sei valori come nella domanda, è definito in this part of the CSS standard.

Quindi la trasformazione, ad es. la rotazione deve essere decodificata. Ci possono essere molte semplici trasformazioni supportate direttamente dai CSS, ad es. tradurre, ridimensionare, ruotare, inclinare e prospettiva. Se viene applicato solo uno di questi, è sufficiente ripristinare la procedura di computing the transform matrix.

Un'alternativa è trovare o tradurre il codice che fa questo per te in JS, ad es. the same document o Section 7.1 of the CSS standard contiene tali algoritmi annotati. Il vantaggio è che l'approccio unmatrix è in grado, con alcune limitazioni, di restituire le trasformazioni "atomiche" anche se viene applicato più di uno di questi (traslazione, rotazione, ecc.). Dal momento che non è possibile garantire il successo del reverse engineering dei passaggi di trasformazione per il caso generale, è utile pensare a quali tipi di trasformazioni possono essere applicati e se sono stati evitati casi degenerati o altri casi problematici. Cioè hai bisogno di costruire la soluzione come meglio credi per il tuo problema.

In particolare, le versioni di matrice di tutte le trasformazioni CSS 2D sono documented here as well, al di sotto del significato dei sei valori nel vettore di trasformazione 2D CSS.

Un'altra avvertenza è che ci sono altre cose che influenzano il risultato visivo in termini di operazioni geometriche, ad esempio, transform-origin.

0

modo facile per estrarre i singoli valori da una complessa trasformazione del valore:

function parseComplexStyleProperty(str){ 
 
    var regex = /(\w+)\((.+?)\)/g, 
 
     transform = {}, 
 
     match; 
 

 
    while(match = regex.exec(str)) 
 
     transform[match[1]] = match[2]; 
 
    
 
    return transform; 
 
} 
 

 
////////////////////////////////////////// 
 

 
var dummyString = "translateX(-50%) scale(1.2)", 
 
    transformObj = parseComplexStyleProperty(dummyString); 
 

 
console.log(transformObj);

Problemi correlati