8

I'm having trouble applying a <mask> layer to a <g> path group.

When I apply my <mask> to a <rect>, it works as expected, but when using it on a <g>, the entire group disappears.

Here's my document

<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="600px" height="600px" viewBox="0 0 600.000000 600.000000" preserveAspectRatio="xMidYMid meet">

     <defs>
        <mask id="myMask" maskUnits="userSpaceOnUse" x="0" y="0" width="600" height="600">
            <rect fill="white" x="0" y="0" width="600" height="600"></rect>
            <circle cx="30" cy="30" r="20" fill="black"></circle>
            <circle cx="300" cy="300" r="200" fill="black"></circle>
        </mask>
     </defs>

     <rect fill="#FFFFFF" width="21456" height="21456" mask="url(#myMask)"></rect>

     <g transform="translate(0.000000,600.000000) scale(0.100000,-0.100000)" fill="#100059" stroke="none" mask="url(#myMask)"> <!-- a bunch of <path>s --> </g>

     <g transform="translate(0.000000,600.000000) scale(0.100000,-0.100000)" fill="#f542b3" stroke="none"> <!-- a bunch of <path>s --> </g>

</svg>

I've also tried a similar method using clip-path with the same results - working with <rect> but not <g>. I've also tried applying the mask property to individual <path> elements with the same result

Any help appreciated

Doug
  • 859
  • 1
  • 9
  • 20

1 Answers1

10

I severely doubt whether this question is still active, but I thought I'd put an answer here anyway, for anyone else.

To mask a group of elements all at the same time, contain them all within a <g></g> block. Then you have a couple of options:

Easy Style: set opacity on all elements

If you are happy having an opacity or other transformation across the whole group, give the <g></g> element a class or ID, and set CSS accordingly:

<g id="someGroup" class="class1 class2">
  <path ...></path>
  <circle ...></circle>
  <whatever ...></whatever>
</g>

and the CSS (probably not all together, but you get the idea):

g,
#someGroup,
.class1,
.class2 {
    opacity: 0.5;
}

# Less Easy: set up a mask and apply to the group (OP question) # First you will have to set up the mask in the <defs></defs> block with an ID, then apply it to the group. An example:
<mask id="easyMask" x="0" y="0" width="1" height="1"
    maskContentUnits="objectBoundingBox">
    <rect x="0" y="0" width="1" height="1"
        style="fill-opacity: 0.25; fill: white;"/>
</mask>

I won't explain the masking element because the OP seems to know that already. However, for a thorough guide, to the MDN reference and have a read. Anyway, once you have your mask set up in defs, apply it to the group thusly:

<g style="mask: url(#easyMask);">
  <path ...></path>
  <circle ...></circle>
  <whatever ...></whatever>
</g>

Most important part of this is the style element style="mask: url(#easyMask);" which actually applies the mask. It will work on all child elements of the g group. Just relace #easyMask with the ID of your mask and you're good to go! Haven't tried it with any other selectors (like .class1 or something) but the presence of the # seems to indicate CSS-style selectors. Have an experiment :-)

atlas_scoffed
  • 3,542
  • 30
  • 46
Katstevens
  • 1,556
  • 13
  • 29