Home > OS >  Is it possible to have two different colors within the same path without using CSS?
Is it possible to have two different colors within the same path without using CSS?

Time:03-16

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>

  • Related