简体   繁体   中英

SVG in HTML: How to use a multicolored SVG as a mask

I know how to use SVG masks to completely "cut out" the mask in another shape, if the mask is monochrome.

How can I use a multicolored SVG definition X as the mask so that the outer shape of X defines the "hole" to be cut out?

Here are three images that illustrate what I am trying to achieve:

svg #1 to be used as mask

svg #2 on which the outer shape of #1 should be used as a cut-out

result

Creating a white-filled version of the shape as @enxaneta proposed is not applicable to my problem, as I have many "complicated" external SVG definitions, and I don't want to change every single one of them.

Is there another, simpler way to achieve what I want?

The colour of a mask determines the final opacity of the masked object at that point. The R, G, B, and A components of the mask colour are combined in a formula to determine a luminance value that is used to set the final transparency that the mask will be a that point. So, for example, if the mask is red, the final masked result will be semi transparent.

There is no way to make a coloured object be a solid (not translucent) mask. Only full white will do that.

Update

Assuming you have an external SVG image that looks like the following:

 <svg viewBox="0 0 100 50"> <polygon id="a" points="30,5 70,20 75,40 20,20" fill="lightblue"/> <circle id="b" cx="50" cy="25" r="15" fill="gold"/> <circle id="c" cx="60" cy="35" r="10" fill="red" stroke="blue" stroke-width="4"/> </svg> 

You can turn this into a "mask" version by adding three lines to the start of your SVG.

 <svg viewBox="0 0 100 50"> <filter id="blacken"><feFlood flood-color="black"/><feComposite operator="in" in2="SourceGraphic"/></filter> <style>svg :not(#maskbg) { filter: url(#blacken); }</style> <rect id="maskbg" x="-100%" y="-100%" width="300%" height="300%" fill="white"/> <polygon id="a" points="30,5 70,20 75,40 20,20" fill="lightblue"/> <circle id="b" cx="50" cy="25" r="15" fill="gold"/> <circle id="c" cx="60" cy="35" r="10" fill="red" stroke="blue" stroke-width="4"/> </svg> 

This is something that could easily be scripted. This method should work for almost all SVGs.

Once you have all the mask variants built, you can apply them using mask-image .

https://developer.mozilla.org/en-US/docs/Web/CSS/mask-image

You need to define your paths with no fill. Then you use your paths for the mask and fill them with white. To draw the image you fill those paths with the colors of your choice.

 svg{border:1px solid; width:49vw} svg:nth-child(2){background:red;} mask use{fill:white;} 
 <svg viewBox="0 0 100 50"> <defs> <polygon id="a" points="30,5 70,20 75,40 20,20" /> <circle id="b" cx="50" cy="25" r="15" /> <circle id="c" cx="60" cy="35" r="10" /> <mask id="m"> <use xlink:href="#a"/> <use xlink:href="#b"/> <use xlink:href="#c"/> </mask> </defs> <g id="complexShape"> <use xlink:href="#a" fill="lightblue" /> <use xlink:href="#b" fill="gold"/> <use xlink:href="#c" fill="red"/> </g> </svg> <svg viewBox="0 0 100 50"> <rect width="100" height="50" style="mask: url(#m)" /> </svg> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM