SVG supports the following clipping/masking features:
One key distinction between a clipping path and a mask is that clipping paths are hard masks (i.e., the silhouette consists of either fully opaque pixels or fully transparent pixels, with the possible exception of antialiasing along the edge of the silhouette) whereas masks consist of an image where each pixel value indicates the degree of transparency vs. opacity. In a mask, each pixel value can range from fully transparent to fully opaque.
SVG supports only simple alpha blending compositing (see Simple Alpha Blending/Compositing).
(Insert drawings showing a clipping path, a grayscale imagemask, simple alpha blending and more complex blending.)
Graphics elements are blended into the elements already rendered on the canvas using simple alpha blending/compositing, in which the resulting color and opacity at any given pixel on the canvas is the result of the following formulas (all color values use premultiplied alpha):
Er, Eg, Eb - Element color value Ea - Element opacity/alpha value Cr, Cg, Cb - Canvas color value (before blending) Ca - Canvas opacity/alpha value (before blending) Cr', Cg', Cb' - Canvas color value (after blending) Ca' - Canvas opacity/alpha value (after blending) Ca' = 1 - (1 - Ea) * (1 - Ca) Cr' = (1 - Ea) * Cr + Er Cg' = (1 - Ea) * Cg + Eg Cb' = (1 - Ea) * Cb + Eb
The following rendering properties, which provide information about the color space in which to perform the compositing operations, apply to compositing operations:
The clipping path restricts the region to which paint can be applied. Conceptually, any parts of the drawing that lie outside of the region bounded by the currently active clipping path are not drawn. A clipping path can be thought of as a 1-bit mask.
When an 'svg' element is encountered by a CSS user agent, the CSS user agent needs to establish an initial clipping path for the SVG document fragment. The 'overflow' and 'clip' properties from CSS2 along with additional SVG user agent processing rules determine the initial clipping path which the CSS user agent establishes for the SVG document fragment:
Value: | visible | hidden | scroll | auto | inherit |
Initial: | visible (see notes below) |
Applies to: | elements which establish a new viewport |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Animatable: | N/A |
The 'overflow' property has the same parameter values and has the same meaning as defined in [CSS2-overflow]; however, the following additional points apply:
As a result of the above, the default behavior of SVG user agents is to establish a clipping path to the bounds of the initial viewport and to establish a new clipping path for each element which establishes a new viewport.
For stand-alone SVG viewers or in situations where an SVG document fragment is embedded inline within a parent XML grammar which does not use CSS layout or XSL formatting, then the initial clipping path must be set to the bounds of the viewing region in which the SVG document fragment is rendered, even if the and the 'overflow' property is set to a value other than hidden.
For related information, see Clip to viewport vs. clip to viewBox.
Value: | <shape> | auto | inherit |
Initial: | auto |
Applies to: | elements which establish a new viewport |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Animatable: | N/A |
The 'clip' property only applies to elements which establish a new viewport. The 'clip' property has the same parameter values as defined in [CSS2-clip]. Unitless values, which indicates current user coordinates, are permitted on the coordinate values on the <shape>. The value of "auto" indicates defines a clipping path along the bounds of the viewport created by the given element.
It is important to note that initial values for the 'overflow' and 'clip' properties and the Default style sheet for SVG will result in an initial clipping path that is set to the bounds of the initial viewport. When attributes viewBox and preserveAspectRatio attributes are specified on a viewport-creating element, it is sometime desirable that the initial viewport be set to the bounds of the viewBox instead of the viewport, particularly when preserveAspectRatio specifies uniform scaling and the aspect ratio of the viewBox does not match the aspect ratio of the viewport.
To set the initial clipping path to the bounds of the
viewBox
instead of the viewport, set the bounds of
'clip'
property to the same rectangle as specified on the
viewBox
attribute. (Note that the parameters don't match.
'clip'
takes values <top>, <right>,<bottom> and <left>, whereas
viewBox
takes values <min-x>, <min-y>, <width> and <height>.)
A clipping path is defined with a 'clipPath' element. A clipping path is used/referenced using the 'clip-path' property.
A 'clipPath' element can contain 'path' elements, 'text' elements, other vector graphic shapes (such as 'circle') or a 'use' element. If a 'use' element is a child of a 'clipPath' element, it must directly reference path, text or vector graphic shape elements. Indirect references are an error (see Error processing). The silhouettes of the child elements are logically OR'd together to create a single silhouette which is then used to restrict the region onto which paint can be applied.
It is an error if the 'clip-path' property references a non-existent object or if the referenced object is not a 'clipPath' element (see Error processing).
For a given graphics element, the actual clipping path used will be the intersection of the clipping path specified by its 'clip-path' property (if any) with any clipping paths on its ancestors, as specified by the 'clip-path' property on the ancestor elements.
A couple of notes:
<!ENTITY % clipPathExt "" > <!ELEMENT clipPath (%descTitle;, (path|text|rect|circle|ellipse|line|polyline|polygon| use|animate|set|animateMotion|animateColor|animateTransform %ceExt;%clipPathExt;)*) > <!ATTLIST clipPath id ID #IMPLIED xml:lang NMTOKEN #IMPLIED xml:space (default|preserve) #IMPLIED class NMTOKENS #IMPLIED style CDATA #IMPLIED clipPathUnits (userSpace | userSpaceOnUse | objectBoundingBox) "userSpace" > |
Attribute definitions:
Value: | <uri> | none | inherit |
Initial: | See The initial clipping path: 'overflow' and 'clip' properties |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Animatable: | yes |
Value: | evenodd | nonzero | inherit |
Initial: | evenodd |
Applies to: | all elements |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Animatable: | yes |
In SVG, you can specify that any other graphics object or 'g' element can be used as an alpha mask for compositing the current object into the background.
A mask is defined with a 'mask' element. A mask is used/referenced using the 'mask' property.
A 'mask' can contain any graphical elements or grouping elements such as a 'g'.
It is an error if the 'mask' property references a non-existent object or if the referenced object is not a 'mask' element (see Error Processing).
The effect is as if the child elements of the 'mask' are rendered into an offscreen image. Any graphical object which uses/references the given 'mask' element will be painted onto the background through the mask, thus completely or partially masking out parts of the graphical object.
The following processing rules apply:
Note that SVG 'path''s, shapes (e.g., 'circle') and 'text' are all treated as four-channel RGBA images for the purposes of masking operations.
In the following example, an image is used to mask a rectangle:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG December 1999//EN" "http://www.w3.org/Graphics/SVG/SVG-19991203.dtd"> <svg width="4in" height="3in"> <desc>Example of using a mask </desc> <g> <defs> <mask id="MyMask"> <image xlink:href="transp.png" /> </mask> </defs> <rect style="mask: url(#MyMask)" width="12.5" height="30" /> </g> </svg>
A <mask> element can define a region on the canvas for the mask using the following attributes:
<!ENTITY % maskExt "" > <!ELEMENT mask (%descTitleDefs;, (path|text|rect|circle|ellipse|line|polyline|polygon| use|image|svg|g|switch|a| animate|set|animateMotion|animateColor|animateTransform %ceExt;%maskExt;)*) > <!ATTLIST mask id ID #IMPLIED xml:lang NMTOKEN #IMPLIED xml:space (default|preserve) #IMPLIED class NMTOKENS #IMPLIED style CDATA #IMPLIED maskUnits (userSpace | userSpaceOnUse | objectBoundingBox) "userSpace" x CDATA #IMPLIED y CDATA #IMPLIED width CDATA #IMPLIED height CDATA #IMPLIED > |
Attribute definitions:
The following is a description of the 'mask' property.
Value: | <uri> | none | inherit |
Initial: | none |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Animatable: | yes |
There are several opacity properties within SVG:
Except for object/group opacity (described just below), all other opacity properties are involved in intermediate rendering operations. Object/group opacity can be thought of conceptually as a postprocessing operation. Conceptually, after the object/group is rendered into an RGBA offscreen image, the object/group opacity setting specifies how to blend the offscreen image into the current background.
Value: | <alphavalue> | inherit |
Initial: | 1 |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Animatable: | yes |
Example opacity01, illustrates various usage of the 'opacity' property on elements and groups.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG December 1999//EN" "http://www.w3.org/Graphics/SVG/SVG-19991203.dtd"> <svg width="12cm" height="3.5cm"> <desc>Example opacity01 - opacity property</desc> <!-- Background blue rectangle --> <rect x="1cm" y="1cm" width="10cm" height="1.5cm" style="fill:#0000ff" /> <!-- Red circles going from opaque to nearly transparent --> <circle cx="2cm" cy="1cm" r=".5cm" style="fill:red; opacity:1" /> <circle cx="4cm" cy="1cm" r=".5cm" style="fill:red; opacity:.8" /> <circle cx="6cm" cy="1cm" r=".5cm" style="fill:red; opacity:.6" /> <circle cx="8cm" cy="1cm" r=".5cm" style="fill:red; opacity:.4" /> <circle cx="10cm" cy="1cm" r=".5cm" style="fill:red; opacity:.2" /> <!-- Opaque group, opaque circles --> <g style="opacity:1"> <circle cx="1.825cm" cy="2.5cm" r=".5cm" style="fill:red; opacity:1" /> <circle cx="2.175cm" cy="2.5cm" r=".5cm" style="fill:green; opacity:1" /> </g> <!-- Group opacity: .5, opacity circles --> <g style="opacity:.5"> <circle cx="3.825cm" cy="2.5cm" r=".5cm" style="fill:red; opacity:1" /> <circle cx="4.175cm" cy="2.5cm" r=".5cm" style="fill:green; opacity:1" /> </g> <!-- Opaque group, semi-transparent green over red --> <g style="opacity:1"> <circle cx="5.825cm" cy="2.5cm" r=".5cm" style="fill:red; opacity:.5" /> <circle cx="6.175cm" cy="2.5cm" r=".5cm" style="fill:green; opacity:.5" /> </g> <!-- Opaque group, semi-transparent red over green --> <g style="opacity:1"> <circle cx="8.175cm" cy="2.5cm" r=".5cm" style="fill:green; opacity:.5" /> <circle cx="7.825cm" cy="2.5cm" r=".5cm" style="fill:red; opacity:.5" /> </g> <!-- Group opacity .5, semi-transparent green over red --> <g style="opacity:.5"> <circle cx="10.175cm" cy="2.5cm" r=".5cm" style="fill:red; opacity:.5" /> <circle cx="9.825cm" cy="2.5cm" r=".5cm" style="fill:green; opacity:.5" /> </g> </svg>
View this example as SVG (SVG-enabled browsers only)
In the example above, the top row of circles have differing opacities, ranging from 1.0 to 0.2. The bottom row illustrates five 'g' elements, each of which contains overlapping red and green circles, as follows:
The SVGClipPath interface corresponds to the clipPath element.
interface SVGClipPath : SVGStyledElement { // clipPathUnit Types const unsigned short kSVG_CLIPPATHUNITS_UNKNOWN = 0; const unsigned short kSVG_CLIPPATHUNITS_USERSPACE = 1; const unsigned short kSVG_CLIPPATHUNITS_USERSPACEONUSE = 2; const unsigned short kSVG_CLIPPATHUNITS_OBJECTBOUNDINGBOX = 3; attribute unsigned short clipPathUnits; }; |
The SVGMask interface corresponds to the 'mask' element.
interface SVGMask : SVGStyledElement { // maskUnit Types const unsigned short kSVG_MASKUNITS_UNKNOWN = 0; const unsigned short kSVG_MASKUNITS_USERSPACE = 1; const unsigned short kSVG_MASKUNITS_USERSPACEONUSE = 2; const unsigned short kSVG_MASKUNITS_OBJECTBOUNDINGBOX = 3; attribute unsigned short maskUnits; attribute SVGLength x; attribute SVGLength y; attribute SVGLength width; attribute SVGLength height; }; |