2010-07-28 14 views
11

Me gustaría dibujar una forma que tenga agujeros en ella de modo que pueda fill darle forma y no tener los agujeros llenos de ese color (dejarlos transparentes).Cómo conseguir 'rosquillas' con sendas en Rafael

Según la W3 path spec:

trazados compuestos (es decir, una ruta con múltiples subrutas) son posibles para permitir efectos tales como "agujeros de donuts" en objetos.

¿Alguien puede por favor dar un ejemplo muy simple de cómo realizar esto con una ruta de vector en Raphael?

Muchas gracias.

+0

De hecho, no es específico de Rafael pero más generaly a SVG. – challet

Respuesta

18

Esto resulta bastante sencillo si conoce el truco. Por ejemplo this doesn't work:

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" + 
      " M 75 75 L 75 125 L 125 125 L 125 75 z") 
.attr("fill", "#f00"); 

Pero this does work *:

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" + 
      " M 75 75 L 125 75 L 125 125 L 75 125 z") 
.attr("fill", "#f00"); 

La diferencia es que para que aparezca la dona el camino interior tiene que tener su vértices dibujados en orden inverso a la vía externa (es decir, dibuja uno en el sentido de las agujas del reloj, el otro en sentido antihorario). Un bocado que encontré en el text.xml.svg.devel archives.

(*) Por lo menos, funciona en Chrome, Opera y Firefox 4.0 beta, pero no en 3,6

+0

Estoy tratando de usar esta técnica para llenar una rosquilla circular, ¿alguna idea de cómo hacer que la función del círculo dibuje en reversa para que se llene correctamente? – Neil

+0

@Neil Por lo que sé, debe usar rutas para que esto funcione. – robertc

+0

@robertc gracias. Lo logré con caminos, gracias por la sugerencia. – Neil

4

Para que esto funcione en Firefox 3.6, es necesario cerrar el agujero; es decir, hacer que las coordenadas se vuelvan a unir a sí mismas al definir el límite interno. Curiosamente, esto no parece necesario para el límite exterior.

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" + 
      " M 75 75 L 125 75 L 125 125 L 75 125 L 75 75 z") 
.attr("fill", "#f00"); 

Sólo una nota rápida para seguir arriba en el comentario - el concepto/hacia la izquierda hacia la derecha puede parecer extraño al principio, pero es bastante estándar en toda tecnologías GIS/CAD.

+0

Hola @ Ben. Estoy buscando lo contrario de su solución, por favor. Y aquí está mi pregunta: http://stackoverflow.com/questions/20847767/how-to-change-an-svgs-complex-paths-that-have-duplicated-paths-for-each-line-to – user3117671

3

Creo que la forma correcta de hacerlo es establecer el atributo "fill-rule" en el valor "evenodd". Eche un vistazo al svg spec:

No intente configurarlo con "Raphael.Element.attr()". No funciona Yo uso la función jQuery.attr() en su lugar:

// assuming paper is a Raphael.Paper object 
path = paper.path('Mx,y{some path commands for the main shape}Z' 
        +'Mx,y{some path commands for the hole}Z' 
); 

// this doesn't work 
path.attr({'fill-rule': 'evenodd'}); 
// neither this 
path.attr({fillRule: 'evenodd'}); 

// if you inspect the object returned by paper.path 
// you can see it has a reference to the DOM element 
console.debug(path) 

// so a bit of jQuery and it's done 
$(path[0]).attr('fill-rule', 'evenodd'); 

He utilizado este en las trayectorias complejas con resultados exitosos.

+0

Just wanted para dar una actualización no jQuery para esto: 'ruta [0] .setAttribute ('llenar en reglas', 'EVENODD');' obras – Howard

2

para cualquiera que quiera hacer rosquillas circulares, gran plugin fácil Raphael-donut-plugin

Síntesis:

Raphael.fn.donut = function(x, y, innerRadius, outerRadius) { 
    y -= outerRadius; 
    return this.path('M'+x+' '+y+'a'+outerRadius+' '+outerRadius + 
     ' 0 1 0 1 0m-1 '+ 
     (outerRadius - innerRadius)+ 
     'a'+innerRadius+' '+innerRadius+ 
     ' 0 1 1 -1 0'); 
}; 
+0

si se agrega un ejemplo violín que sería grande – Muhammed

Cuestiones relacionadas