svg - Cómo hacer que el ancho del trazo sea inmune a la matriz de transformación actual
postscript coordinate-transformation (2)
En SVG (y Canvas, Quartz, Postscript, ...), la matriz de transformación afecta tanto a las coordenadas de ruta como a la anchura de línea. ¿Hay alguna manera de hacer un ajuste para que el ancho de la línea no se vea afectado? Es decir, en el siguiente ejemplo, la escala es diferente para X e Y, lo que hace que el cuadrado se convierta en un rectángulo, lo que está bien, pero también hace que las líneas sean más anchas en ambos lados.
<g transform="rotate(30) scale(5,1) ">
<rect x="10" y="10" width="20" height="20"
stroke="blue" fill="none" stroke-width="2"/>
</g>
Puedo ver que sería útil en muchos casos, pero ¿hay alguna manera de optar por no participar? Supongo que me gustaría tener una pluma independiente TM o poder configurar la pluma para que sea una elipse que la CTM convierte en un círculo, pero no veo nada de eso.
Al carecer de eso, creo que no debo decirle a SVG sobre mi CTM y en su lugar, transformar las coordenadas, lo que significa convertir primitivas como rect
en sus equivalentes de path
.
En postscript, describir la ruta y realizar el trazo son eventos separados, por lo que es perfectamente posible tener una TM "pluma" por separado.
%!PS
%A Funky Shape
matrix currentmatrix %save normal matrix for stroke pen
306 396 translate
72 72 scale
1 1 5 { pop
360 5 div rotate
1 0 translate
0 0 moveto
1 1 5 { pop
360 5 div rotate
1 0 translate
1 0 lineto
-1 0 translate
} for
-1 0 translate
closepath
} for
setmatrix
[ 1 -3 4 2 0 0 ] concat %put some skew in the pen
10 rotate %makes it look more "organic"
stroke
showpage
Editar:
Hay un atributo que puede agregar a su rect para obtener exactamente este comportamiento:
vector-effect="non-scaling-stroke"
Esto estuvo mal:
Esto funcionará si aplica la transformación directamente a la forma, no al grupo en el que se encuentra. Por supuesto, si desea agrupar varios elementos y escalarlos todos juntos, ese enfoque no funcionará.
<rect x="10" y="10" width="20" height="20"
stroke="blue" fill="none" stroke-width="2"
transform="rotate(30) scale(5,1)"/>
Esto también puede depender de su visor SVG; Inkscape renderiza su archivo de la manera que desee (el ancho del trazo no se ve afectado por la escala) pero Chrome lo representa como lo ha mostrado.