Dilata y erosiona las formas SVG usando Javascript

EDITAR:

Finalmente encontré una forma de erosionar y dilatar polígonos (desplazamiento) para que la nueva geometría se cree utilizando la biblioteca Clipper: https://sourceforge.net/projects/jsclipper/

Demostración en vivo de Javascript Clipper: http://jsclipper.sourceforge.net/5.0.2.1/main_demo.html

El Clipper solo puede manejar polígonos o polígonos múltiples (p. Ej., Polígonos con agujeros), por lo que para que funcione con otros objetos gráficos en formato SVG, deben convertirse en líneas rectas. Al menos, las rutas son bastante fáciles de convertir en líneas usando path.getTotalLength() y path.getPointAtLength() ( http://whaticode.com/2012/02/01/converting-svg-paths-to-polygons/ ).

La otra posibilidad es usar esta técnica similar (que no crea una nueva geometría): https://stackoverflow.com/a/12723835/1691517


¿Hay alguna forma de erosionar y dilatar formas en SVG a través de Javascript?

Tengo el siguiente ejemplo de SVG: http://jsfiddle.net/timo2012/2S4Kt/1/

Hay tres formas, el azul es original, el verde está erosionado (adelgazado) y el rojo está dilatado (en negrita). Se hacen en ilustrador.

He probado los filtros de erosión y dilatación, pero el efecto no es tan bueno: https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/examples/feMorphology.svg

Después de algunas horas de búsqueda en Internet, solo he encontrado ejemplos de erosión y dilatación de imágenes de bitmap, pero nada sobre formas vectoriales.

He logrado dilatar y erosionar los polígonos SVG utilizando Shapely ( http://toblerity.github.com/shapely/manual.html ) en Python al enviar puntos de ruta a través de la llamada Ajax al script PHP, lo que hace que system () realice la llamada al script Python. pero este método es lento y requiere que el servidor haga el trabajo que se podría hacer del lado del cliente.

Este es mi código para dilatar y erosionar en Python (como puede ver, es bastante corto):

 #!/usr/bin/python26 from shapely.geometry import Polygon from shapely.geometry import MultiPolygon import sys if len(sys.argv)>2: inset=eval(sys.argv[1]) coords=eval(sys.argv[2]) else: sys.exit() bowtie = Polygon(coords) clean = bowtie.buffer(inset) clean = clean.simplify(1, preserve_topology=False) if clean.length>0: if clean.geom_type=="MultiPolygon": for n in range(0, len(clean)): print list(clean[n].exterior.coords) #print "\n" elif clean.geom_type=="Polygon": print list(clean.exterior.coords) 

También encuentre este documento, que intenta definir dilatar y erosionar en términos matemáticos: http://en.wikipedia.org/wiki/Mathematical_morphology

Hay una frase: “La idea básica de la morfología binaria es explorar una imagen con una forma simple y predefinida, y sacar conclusiones sobre cómo esta forma se ajusta o no a las formas en la imagen. Esta simple” sonda “se llama elemento de estructuración. y es en sí misma una imagen binaria (es decir, un subconjunto del espacio o cuadrícula) “.

Supongo que este método podría usarse para transformar formas vectoriales, pero cómo …

EDITAR: Un comentario en una respuesta planteó un posible problema al usar filtros en lugar de crear una nueva geometría: si alguien quiere agregar controles de arrastre a puntos de polígono, entonces los controles de arrastre pueden parecer estar en el lugar incorrecto. Esto puede ser aceptable, porque entonces la impresión es que los datos de la ruta original están intactos, lo que en realidad es el caso de los filtros, pero, después de más pruebas, demostró que la calidad es un problema mayor. De acuerdo con esto y este filtro SVG utiliza la representación de píxeles del objeto gráfico vectorial en lugar de los datos de la ruta en sí, lo que conduce a resultados no tan atractivos .

EDIT2: POSIBLE SOLUCIÓN DE TRABAJO: Una de las respuestas en esta página me llevó a usar trazos y máscaras de ancho variable para lograr una solución atractiva a este problema. Hice algunas pruebas y me implementé un efecto de ruta compensada similar a Adobe Illustrator .

Puede obtener lo que parece ser después de trazar con diferentes anchos de trazo en combinación con clip-path o la mask . Aquí hay un ejemplo , algunas explicaciones de cómo está construido, vea aquí y aquí (flecha arriba o abajo para ver otras diapositivas de ese ejemplo).

Sin embargo, no le da una nueva geometría, solo algo que podría parecer una nueva geometría.

¿Realmente has probado los filtros nativos de SVG? Esto se ve lo suficientemente cerca:

               

Hay un recorte en el filtro de dilate que parece que no puede resolverse aumentando la región del filtro, pero aparte de eso, es bastante similar a la representación del ilustrador. Sure beats renderizado del lado del servidor.

http://jsfiddle.net/5Qv5v/