Clipping and masking

  • Revision slug: SVG/Tutorial/Clipping_and_masking
  • Revision title: Clipping and masking
  • Revision id: 47317
  • Created:
  • Creator: Manuel_Strehl
  • Is current revision? No
  • Comment 194 words added

Revision Content

{{ PreviousNext("SVG/Tutorial/Basic_Transformations", "SVG/Tutorial") }}

Erasing part of what one has created cumbersome might at first sight look contradictory. But when you try to create a semicircle in SVG, you will find out the use of the following properties quickly.

Clipping refers to removing parts of elements defined by other parts. In this case, any half-transparent effects are not possible.

Masking on the other hand allows soft edges by taking transparency and grey values of the mask into account.

Creating clips

We create the above mentioned semicircle based on a circle element:

<clipPath id="cut-off-bottom">
  <rect x="0" y="0" width="200" height="100" />
</clipPath>

<circle cx="100" cy="100" r="100" clip-path="url(#cut-off-bottom)" />

Centered at (100,100) a circle with radius 100 is painted. The attribute clip-path references a clipPath element with a single rect element. This element would paint the upper half of the canvas black.

The rect will not be painted, however. Instead its pixel data will be used to determine, which pixels of the circle "make it" to the final rendering. Since the rectangular covers only the upper half of the circle, the lower half of the circle will vanish:

clipdemo.png

We now have a semicircle without having to deal with arcs in path elements.

Masking

The effect of masking is most impressively presented with a gradient. If you want an element to fade out, you can achieve this effect quite quickly with masks.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="Gradient">
      <stop offset="0" stop-color="white" stop-opacity="0" />
      <stop offset="1" stop-color="white" stop-opacity="1" />
    </linearGradient>
    <mask id="Mask">
      <rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"  />
    </mask>
  </defs>

  <rect x="0" y="0" width="200" height="200" fill="green" />
  <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" />
</svg>

A

Transparency with opacity

There is a simple possibility to set the transparency for a whole element. It's the opacity attribute:

<rect x="0" y="0" width="100" height="100" opacity=".5" />

The above rectangular will be painted half-transparent. For the fill and stroke there are two separate attributes, fill-opacity and stroke-opacity, that control each of those property opacities separately. Note, that the stroke will be painted on top of the filling. Hence, if you set a stroke opacity on an element, that also has a fill, the fill will shine through on half of the stroke, while on the other half the background will appear:

<rect x="0" y="0" width="200" height="200" fill="blue" />
<circle cx="100" cy="100" r="50" stroke="yellow" stroke-width="40" stroke-opacity=".5" fill="red" />

opacitydemo.png

You see in this example the red circle on blue background. The yellow stroke is set to 50% opacity, which leads effectively to a double-color stroke.

{{ PreviousNext("SVG/Tutorial/Basic_Transformations", "SVG/Tutorial") }}

Revision Source

<p>{{ PreviousNext("SVG/Tutorial/Basic_Transformations", "SVG/Tutorial") }}</p>
<p>Erasing part of what one has created cumbersome might at first sight look contradictory. But when you try to create a semicircle in SVG, you will find out the use of the following properties quickly.</p>
<p><strong>Clipping</strong> refers to removing parts of elements defined by other parts. In this case, any half-transparent effects are not possible.</p>
<p><strong>Masking</strong> on the other hand allows soft edges by taking transparency and grey values of the mask into account.</p>
<h3>Creating clips</h3>
<p>We create the above mentioned semicircle based on a <code>circle</code> element:</p>
<pre>&lt;clipPath id="cut-off-bottom"&gt;
  &lt;rect x="0" y="0" width="200" height="100" /&gt;
&lt;/clipPath&gt;

&lt;circle cx="100" cy="100" r="100" clip-path="url(#cut-off-bottom)" /&gt;
</pre>
<p>Centered at (100,100) a circle with radius 100 is painted. The attribute <code>clip-path</code> references a <code>clipPath</code> element with a single <code>rect</code> element. This element would paint the upper half of the canvas black.</p>
<p>The <code>rect</code> will not be painted, however. Instead its pixel data will be used to determine, which pixels of the circle "make it" to the final rendering. Since the rectangular covers only the upper half of the circle, the lower half of the circle will vanish:</p>
<p><img alt="clipdemo.png" class="internal default" src="/@api/deki/files/4933/=clipdemo.png"></p>
<p>We now have a semicircle without having to deal with arcs in path elements.</p>
<h3>Masking</h3>
<p>The effect of masking is most impressively presented with a gradient. If you want an element to fade out, you can achieve this effect quite quickly with masks.</p>
<pre class="xml">&lt;svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
  &lt;defs&gt;
    &lt;linearGradient id="Gradient"&gt;
      &lt;stop offset="0" stop-color="white" stop-opacity="0" /&gt;
      &lt;stop offset="1" stop-color="white" stop-opacity="1" /&gt;
    &lt;/linearGradient&gt;
    &lt;mask id="Mask"&gt;
      &lt;rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"  /&gt;
    &lt;/mask&gt;
  &lt;/defs&gt;

  &lt;rect x="0" y="0" width="200" height="200" fill="green" /&gt;
  &lt;rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" /&gt;
&lt;/svg&gt;
</pre>
<p>A</p><h3>Transparency with <code>opacity</code></h3>
<p>There is a simple possibility to set the transparency for a whole element. It's the <code>opacity</code> attribute:</p>
<pre>&lt;rect x="0" y="0" width="100" height="100" opacity=".5" /&gt;
</pre>
<p>The above rectangular will be painted half-transparent. For the fill and stroke there are two separate attributes, <code>fill-opacity</code> and <code>stroke-opacity</code>, that control each of those property opacities separately. Note, that the stroke will be painted on top of the filling. Hence, if you set a stroke opacity on an element, that also has a fill, the fill will shine through on half of the stroke, while on the other half the background will appear:</p>
<pre>&lt;rect x="0" y="0" width="200" height="200" fill="blue" /&gt;
&lt;circle cx="100" cy="100" r="50" stroke="yellow" stroke-width="40" stroke-opacity=".5" fill="red" /&gt;
</pre>
<p><img alt="opacitydemo.png" class="internal default" src="/@api/deki/files/4942/=opacitydemo.png"></p>
<p>You see in this example the red circle on blue background. The yellow stroke is set to 50% opacity, which leads effectively to a double-color stroke.</p>
<p>{{ PreviousNext("SVG/Tutorial/Basic_Transformations", "SVG/Tutorial") }}</p>
Revert to this revision