rotate origin javascript css svg transformation perspective

javascript - origin - svg transform scale



Transformada de perspectiva de rutas SVG(distorsiĆ³n de cuatro esquinas) (2)

Esta es mi propuesta de distorsión de arrastre ( comparta su conocimiento, estilo de preguntas y respuestas ).

El ejemplo en vivo está en http://jsfiddle.net/xjHUk/209/ y el código principal es este:
(solo ventana de salida: http://jsfiddle.net/xjHUk/210/embedded/result/ )

function transferPoint (xI, yI, source, destination) { var ADDING = 0.001; // to avoid dividing by zero var xA = source[0].x; var yA = source[0].y; var xC = source[2].x; var yC = source[2].y; var xAu = destination[0].x; var yAu = destination[0].y; var xBu = destination[1].x; var yBu = destination[1].y; var xCu = destination[2].x; var yCu = destination[2].y; var xDu = destination[3].x; var yDu = destination[3].y; // Calcultations // if points are the same, have to add a ADDING to avoid dividing by zero if (xBu==xCu) xCu+=ADDING; if (xAu==xDu) xDu+=ADDING; if (xAu==xBu) xBu+=ADDING; if (xDu==xCu) xCu+=ADDING; var kBC = (yBu-yCu)/(xBu-xCu); var kAD = (yAu-yDu)/(xAu-xDu); var kAB = (yAu-yBu)/(xAu-xBu); var kDC = (yDu-yCu)/(xDu-xCu); if (kBC==kAD) kAD+=ADDING; var xE = (kBC*xBu - kAD*xAu + yAu - yBu) / (kBC-kAD); var yE = kBC*(xE - xBu) + yBu; if (kAB==kDC) kDC+=ADDING; var xF = (kAB*xBu - kDC*xCu + yCu - yBu) / (kAB-kDC); var yF = kAB*(xF - xBu) + yBu; if (xE==xF) xF+=ADDING; var kEF = (yE-yF) / (xE-xF); if (kEF==kAB) kAB+=ADDING; var xG = (kEF*xDu - kAB*xAu + yAu - yDu) / (kEF-kAB); var yG = kEF*(xG - xDu) + yDu; if (kEF==kBC) kBC+=ADDING; var xH = (kEF*xDu - kBC*xBu + yBu - yDu) / (kEF-kBC); var yH = kEF*(xH - xDu) + yDu; var rG = (yC-yI)/(yC-yA); var rH = (xI-xA)/(xC-xA); var xJ = (xG-xDu)*rG + xDu; var yJ = (yG-yDu)*rG + yDu; var xK = (xH-xDu)*rH + xDu; var yK = (yH-yDu)*rH + yDu; if (xF==xJ) xJ+=ADDING; if (xE==xK) xK+=ADDING; var kJF = (yF-yJ) / (xF-xJ); //23 var kKE = (yE-yK) / (xE-xK); //12 var xKE; if (kJF==kKE) kKE+=ADDING; var xIu = (kJF*xF - kKE*xE + yE - yF) / (kJF-kKE); var yIu = kJF * (xIu - xJ) + yJ; var b={x:xIu,y:yIu}; b.x=Math.round(b.x); b.y=Math.round(b.y); return b; }

El resultado se distorsiona correctamente a la perspectiva (dos puntos de fuga uno). El principio del cálculo de perspectiva de dos puntos está here . El script puede manejar datos de ruta SVG si cumple con los siguientes requisitos:

  • Todas las coordenadas son absolutas (lo que significa letras mayúsculas). Mira this
  • Arc ("A") no se usa
  • V y H están normalizados a L

Los arcos se pueden normalizar, pero todavía no he encontrado ningún navegador cruzado. V y H a L es una tarea fácil, debe obtener la última coordenada X o Y utilizada y agregar la que falta después de L.

El mismo script puede manejar también curvas en el camino (las curvas son de Times). El siguiente es exactamente el mismo código, pero el atributo de ruta ("d") es diferente:

http://jsfiddle.net/xjHUk/45/ function dummy(a) {return a;} (Este código no tiene verificación de posiciones inválidas, como la anterior).

Las rutas de los ejemplos anteriores se obtienen de versiones SVG de Arial y Times. Tenga en cuenta que las fuentes utilizan el sistema de coordenadas cartesianas , en el que la coordenada y aumenta cuando se avanza. De lo contrario, SVG usa el sistema de coordenadas Polar, que se usa en imágenes de mapa de bits y css. Esto significa que cuando se utilizan rutas de fuentes SVG en el código anterior, la ruta debe voltearse verticalmente y escalarse al tamaño de letra deseado. Las fuentes TTF (y sus contrapartidas SVG) suelen tener em tamaño 2048, por lo que el cuadro delimitador de glifo es sin escala de 2048 px, que suele ser demasiado cuando la ruta de glifo SVG se convierte en ruta SVG.

Pero si quiere distorsionar otras rutas SVG, entonces no es necesario mover y escalar.

Este es un código bastante largo (debido a la funcionalidad de arrastre), pero creo que se puede lograr el mismo efecto también con cierta forma de transformación css-3D, pero todavía no hay suerte en tal implementación ...

A modo de comparación, un ejemplo de distorsión sin perspectiva (SWF del competidor principal de SVG):
http://www.rubenswieringa.com/code/as3/flex/DistortImage/

Y para una comparación adicional, un ejemplo de cálculo de perspectiva VÁLIDA:
http://zehfernando.com/f/TriangleTest.swf

¿Cómo es posible distorsionar las rutas en SVG en el navegador para que se distorsionen a cierta perspectiva utilizando posiblemente javascript o css? La perspectiva de distorsión se puede hacer fácilmente en Photoshop, Illustrator, etc., pero ¿qué hay de los navegadores?

Esta es la ruta de origen:

Y este es el camino después de la transformación:


La respuesta seleccionada está desactualizada.

Aunque SVG no admite cambiar la perspectiva de los elementos, es posible lograrlo mediante el uso de transformaciones CSS3.

CSS3 es una forma extremadamente poderosa de animar objetos. CSS3 Transform se puede crear y aplicar en tiempo real utilizando Javascript.

Existe un buen soporte para CSS3 Transform, con todas las versiones recientes de los principales navegadores que lo soportan. (IE 8+, Chrome 31+, Safari 7.1+, Opera 26+, Firefox 34+, navegador Android 4.1+). Más información: http://caniuse.com/#feat=transforms2d

Para algunas versiones de navegador necesitaría usar prefijos específicos del navegador para crear las transformaciones. Sin embargo, hay un sitio muy ordenado que explica la buena forma de manejarlo: http://bl.ocks.org/mbostock/10571478

Algunas propiedades de transformación CSS3 son: rotate(angle) , scale(dimension) . Sé que se parecen mucho a las transformaciones SVG rotate(angle) , scale(xy) , pero lo mejor es no tomarlas como iguales ya que hay diferencias fundamentales entre las dos, con CSS3 siendo mucho más poderoso que las transformadas SVG. Además, CSS3 Transforms tiene una perspective propiedad que definitivamente debes mirar.

No hay mejor lugar para encontrar más información sobre las Transformaciones CSS3 que el W3: http://www.w3.org/TR/css3-transforms/

Aquí hay un fragmento de código:

div { height: 150px; width: 150px; } .container { perspective: 500px; border: 1px solid black; background: gray; } .transformed { transform: rotateY(50deg); background: blue; }

<!doctype html> <html> <body> <div class="container"> <div class="transformed"> Hola! He sido transformado!</div> </div> </body> </html>

Feliz transformación!