2010-08-07 21 views
15

La publicación de blog de Webkit del año pasado en 3D transforms explica las diversas 'funciones' de transformación que se pueden usar en la propiedad -webkit-transform. Por ejemplo:¿Cómo se leen los valores de transformación individuales en JavaScript?

#myDiv { 
    -webkit-transform: scale(1.1) rotateY(7deg) translateZ(-1px); 
} 

Mi pregunta: ¿cómo accedes a los valores individuales en JavaScript? Cuando se lee la propiedad webkitTransform del elemento, que acaba de obtener una función Matrix3D() con 16 valores en ella, como este ...

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

¿Hay una manera de simplemente leer el valor de un individuo transformar cosa , como rotateY()? ¿O debo leerlo desde la cadena matrix3d ​​() y cómo?

Respuesta

2

Este link from Apple Dev Reference podría arrojar más luz sobre el tema:

La propiedad webkitTransform es una representación de cadena de un lista de transformar las operaciones. Por lo general, esta lista contiene una sola operación de transformación de matriz . Para las transformaciones 3D , el valor es "matrix3d ​​(...)" con los 16 valores de la matriz homogénea 4x4 entre los paréntesis . Para las transformaciones 2D, el valor es una cadena "matriz (...)" que contiene los 6 valores vectoriales.

1

Dado que solo obtiene el valor final de la matriz del estilo calculado, es posible que tenga que verificar el estilo en línea del elemento o las reglas de la hoja de estilo. Si element.style.webkitTransform no le da nada, puede recorrer las hojas de estilo del documento y ver cuál coincide con su elemento. Luego puede regexar la propiedad webkitTransform para obtener/establecer el valor.

0

Pensé en una posibilidad. Si estás dispuesto a analizar cadenas en JavaScript, utilice

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

luego interpretar data.

+3

-webkit transformada no es un atributo, por lo que no se puede acceder a él a través de atributos, debe acceder estilo objeto asociado con el elemento. – shabunc

3

creo que, como syockit dice, iteración a través de las hojas de estilo es el único camino a seguir, puede utilizar webkitMatchesSelector para descubrir reglas que responden a su 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); 
     } 
    } 
} 

Esto supone marcado algo como esto, añadí algunas reglas y valores adicionales para asegurarse de que estaba sacando los valores correctos. Si usted tiene más de una hoja de estilo, entonces usted necesita para ajustar la primera parte para recorrer todas las hojas de estilo también, y es probable que tenga que hacer frente a la especificidad si su -webkit-transform aparece en más de una regla:

<!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 Gran respuesta, aunque solo funciona para CSS estilos en línea –

+0

Quise decir "aunque solo funciona para hojas de estilo internas" –

+0

Agregué tu código en violín y no puedo obtener ninguna lectura http://jsfiddle.net/ypf2wv4g/9/ – thednp

3

Me encontré con este problema esta mañana. Parece que JavaScript no puede leer la propiedad de un elemento style.webkitTransform hasta que se haya establecido explícitamente en el atributo style del elemento (ya sea en línea en el HTML o en forma de procedimiento mediante JavaScript). Por muy suena que suene, si necesita que JS pueda leer las propiedades de transformación de CSS, es mejor que defina sus valores iniciales con JavaScript cuando el DOM esté listo.

ejemplo, usando jQuery:

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

Desde este punto en adelante, usted será capaz de leer el elemento de transformación de la cadena y analizar a través de él para los valores necesarios.

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*/); 
} 

Hope this helps! Tenga en cuenta que no usé otra biblioteca, excepto la API DOM sencilla y la función nativa de Javascript RegExp. Por lo tanto, esto debería funcionar universalmente cruzando navegadores y aplicaciones.

+0

Aunque esto divide cada valor de la matriz en una matriz, los valores no representan las propiedades de transformación CSS y, por lo tanto, no responde a la pregunta del OP. –

1

puede utilizar expresiones regulares para obtener un mapa de la propiedad-valor:

si transformstyle variable contiene el valor de estilo

//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},{}) 

para:

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

obtendrías:

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

Es sorprendente que una característica tan impresionante no tenga una API de JavaScript más poderosa. Realmente, los valores individuales necesitan ser analizados usando regex? Blech. – freakTheMighty

+0

¡No! El estándar js getComputedStyle devuelve una matriz/matriz3d. Por lo tanto, debe analizar y calcular los datos de la matriz para recuperar las transformaciones CSS. – Jordan

+1

Aunque esto divide cada valor de matriz en una matriz, los valores no representan las propiedades de transformación de CSS y, por lo tanto, no responden a la pregunta del OP. –

1

El hecho de que No vi ningún Javascript una línea de trabajo de soluciones para convertir el código de la matriz, que aquí es mío. Rápido y fácil:

En primer lugar obtener todos los valores de transformar en una matriz:

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

Para extraer transformar-y como un entero:

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

Para extraer transformar-x como un entero:

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

El acceso al valor de rotación es bastante difícil, pero hay una buena guía, si desea t o hazlo: https://css-tricks.com/get-value-of-css-rotation-through-javascript/

3

Una pregunta antigua pero interesante y sin respuesta previa ha intentado responderla.

Lamentablemente, no existe una solución de dos líneas para el caso general y no sabemos qué variedad de pasos de transformación (rotar, traducir, etc.) necesitan ingeniería inversa; cuanto menos, más fácil.

En los navegadores basados ​​en WebKit recientes, simplemente se puede consultar la propiedad previamente asignada:

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

Vamos a continuar con la suposición de que el estilo computarizada necesita ser utilizado. Surge la necesidad, por ejemplo, si el elemento está en el medio de una transición CSS o animación CSS, es decir, la transformación actual no es una que se estableció directamente.

La cadena de descriptor de matriz devuelta por getComputedStyle se puede analizar a través de una expresión regular, pero no todas las versiones anteriores son confiables y son demasiado opacas.Una forma sencilla de romper la cadena, a menos que sea en un bucle muy estrecho como para justificar una expresión regular de un solo paso, es la siguiente:

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

Sin embargo, otra forma es utilizar simplemente esto, que no fue mencionado antes:

var cssMatrix = new WebKitCSSMatrix(matrixString); 

la ventaja de este último enfoque es que vuelvas una matriz de 4x4, así, que es la representación estándar para affine transformations, y el inconveniente es que es por supuesto WebKit específica. Si continúa trabajando con la tupla de seis valores como en la pregunta, se define in this part of the CSS standard.

Luego la transformación, p. Ej. la rotación debe ser de ingeniería inversa. Puede haber muchas transformaciones simples directamente soportadas por CSS, p. Ej. traducir, escalar, girar, sesgar y perspectiva. Si solo se aplica uno de ellos, solo necesita revertir el proceso de computing the transform matrix.

Una alternativa es encontrar o traducir el código que hace esto por usted en JS, p. the same document o Section 7.1 of the CSS standard contiene dichos algoritmos anotados. El beneficio es que el enfoque unmatrix puede, con algunas limitaciones, devolver las transformaciones "atómicas" incluso si se aplica más de una de ellas (traducir, girar, etc.). Como no es posible garantizar la ingeniería inversa exitosa de los pasos de transformación para el caso general, es útil pensar qué tipos de transformaciones posiblemente se apliquen, y si se han evitado casos problemáticos o degenerados. Es decir. necesita construir la solución como mejor le parezca para su problema.

Específicamente, las versiones matriciales de todas las transformaciones CSS 2D son documented here as well, por debajo del significado de los seis valores en el vector de transformación CSS 2D.

Otra advertencia es que hay otras cosas que influyen en el resultado visual en términos de operaciones geométricas, por ejemplo, transform-origin.

0

manera fácil de extraer los valores individuales de una compleja transformación de valor:

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);

Cuestiones relacionadas