I have the following SVG code:
<svg id="cogwheel_1" viewBox="0 0 300 300">
<path fill="black" fill-rule="evenodd" stroke="black" stroke-width="1" d="M 60 60 m -2 5 a 5 5 0 0 1 0 -10 l 4 0 a 5 5 0 0 1 0 10 z m 2 -3 a 2 2 0 0 1 0 -4 a 2 2 0 0 1 0 4 z"></path>
</svg>
You can view it on jsfiddle:
https://jsfiddle.net/Allasso/uk3t875g/4/
The outer section is filled with black. I would like to fill the inner circle with a different color. Is this possible?
I am writing a simple PCB designing tool that can be run from an HTML page. The example you see would be a solder pad. In the approach I am using, it is advantageous to me to make each symbol using a single path, thus I don't want to break it up into two paths. Also, the SVG code needs to be atomic so I can export the code as an SVG file, so I don't want to use CSS to accomplish this. I need everything to be done within a single path if possible.
I have viewed other questions regarding this topic, but the answers suggest "it is easiest to break it up into two paths," however, I am not seeing a definitive "it can't be done using a single path." If there is a way to do this using a single path I would like to know how to do it. If it simply can't be done, I would like to know that.
CodePudding user response:
You are sketchy in giving constraints to the sort of paths you are trying to draw. But for the one you showed, the answer is relatively obvious: paths can have one color for the fill, and another one for the stroke. It is possible to define such a path that your example is reproduced faithfully, using a black stroke and a red fill combined with fill-rule="nonzero"
. I have changed the viewBox
a bit to show the result at a larger scale.
<svg id="cogwheel_1" width="45%" viewBox="40 50 40 20">
<path fill="black" fill-rule="evenodd" stroke="black" stroke-width="1"
d="M 60 60 m -2 5 a 5 5 0 0 1 0 -10 l 4 0 a 5 5 0 0 1 0 10 z m 2 -3 a 2 2 0 0 1 0 -4 a 2 2 0 0 1 0 4 z"></path>
</svg>
<svg id="cogwheel_2" width="45%" viewBox="40 50 40 20">
<path fill="red" fill-rule="nonzero" stroke="black" stroke-width="4"
d="M 60 60 m -2 3.5 a 3.5 3.5 0 0 1 0 -7 l 4 0 a 3.5 3.5 0 0 1 0 7 z m 2 0 a 3.5 3.5 0 0 1 0 -7 a 3.5 3.5 0 0 1 0 7 z"></path>
</svg>
If your characterization of other paths would be "a shape in one color with some parts in the middle with another color", the general strategy for finding a path would be: Draw a partial path for the outer shape and one for the inner shape. Leave room for a generous stroke width. If there is too much space left even after you adjusted the stroke width, so that the fill color is showing in too many places, add a hatching to the path for these areas until you see only the stroke color.
CodePudding user response:
This filter method will fill shapes that have a hole inside them - but you will need to change the radius of the dilate/erode so it matches the maximum radius of the hole (otherwise it will leave an unfilled area).
<svg id="cogwheel_1" width="600px" height="600px" viewBox="0 0 100 100">
<defs>
<filter id="fill-the-holes" x="-50%" y="-50%" width="200%" height="200%">
<feMorphology operator="dilate" radius="2" />
<feMorphology operator="erode" radius="2" result="fat-center"/>
<feFlood flood-color="green"/>
<feComposite operator="in" in2="fat-center"/>
<feComposite operator="over" in='SourceGraphic'/>
</filter>
</defs>
<g filter="url(#fill-the-holes)">
<path fill="black" fill-rule="evenodd" stroke="red" stroke-width="1" d="M 20 20 m -2 5 a 5 5 0 0 1 0 -10 l 4 0 a 5 5 0 0 1 0 15 z m 2 -3 a 2 2 0 0 1 0 -4 a 2 2 0 0 1 0 8 z"/>
</g>
</svg>