Clipping in SVG
Clipping is the business of hiding what normally would be drawn. The stencil which defines what is and what isn't drawn is called a clipping path. In SVG you can define a clipping path by placing shapes, paths and text inside a 'clipPath' element. It is like a special case of an opacity mask as everything is either on or off. The areas taken up by the clip-path graphics are drawn and those outside are transparent.
Clipping paths are used by adding the clip-path attribute to any shape or container tag. The attribute references the clipping path by its id.
Attribute |
Comments |
id |
The unique id that is required to reference the clipping path. |
clip-path |
The referenced clipping path is intersected with the referencing clipping path. |
clipPathUnits |
The values are either 'userSpaceOnUse' or 'objectBoundingBox'. The second value makes units of childern a fraction of the object bounding box which uses the mask. (default: 'userSpaceOnUse') |
The 'clipPath' element can be placed inside the tag of the graphic which uses it or separately in the definition section of your SVG document. Making a clipping path a child of a graphic however will not automatically make the graphic use it. You must still add a clip-path attribute.
<clipPath id="eyeLeftPath"> <ellipse cx="130" cy="75" rx="90" ry="40" transform="skewX(-20)" /> </clipPath> .... <g clip-path="url(#eyeLeftPath)" onmousemove="mouseMove(evt);"> <rect x="0" y="0" width="100%" height="100%" fill="midnightblue" /> <circle id="leftEye" cx="100" cy="75" r="100" fill="url(#eyeGradient)" /> </g>
Intersection and Union
The intersection and union of clipping paths are supported in a limited fashion. SVG supports intersection through the clip-path attribute on a clipPath tag. There is no direct way to intersect 3 or more clipping paths.
There is no syntactic sugar for the union of two or more clipping paths. You just add the same graphics to both. The 'use' element isn't much help as it can only directly reference shapes, text and paths when used in a clipping path.
<clipPath id="clip1"> <polygon id="clip1Shape" points="100,10 40,180 190,60 10,60 160,180 100,10" stroke="blue" /> </clipPath> <clipPath id="clip2"> <circle id="clip2Shape" cx="100" cy="100" r="65" /> </clipPath> <!-- Intersection --> <clipPath id="clipIntersection" clip-path="url(#clip1)"> <use x="0" y="0" width="200" height="200" xlink:href="#clip2Shape" /> </clipPath> <!-- Union --> <clipPath id="clipUnion"> <use x="0" y="0" width="200" height="200" xlink:href="#clip1Shape" /> <use x="0" y="0" width="200" height="200" xlink:href="#clip2Shape" /> </clipPath> .... <!-- Clip 1 --> <rect x="10" y="10" width="180" height="180" fill="url(#myFillGrad)" clip-path="url(#clip1)" /> <!-- Clip 2 --> <rect x="10" y="10" width="180" height="180" fill="url(#myFillGrad)" clip-path="url(#clip2)" transform="translate(200)"/> <!-- Intersection --> <rect x="10" y="10" width="180" height="180" fill="url(#myFillGrad)" clip-path="url(#clipIntersection)" transform="translate(400)" /> <!-- Union --> <rect x="10" y="10" width="180" height="180" fill="url(#myFillGrad)" clip-path="url(#clipUnion)" transform="translate(600)" />
Childern of a clipping path can be any shape, text or path. A child tag is any tag which is inside another tag. All presentation attributes like fill and stroke are ignored as only the shape area is needed to make a clipping path. The 'use' element can be used only if it directly references a shape, text or path. It cannot reference a container element like 'g'.