logo
コーディング

更新日

SVGクリッピングマスクにチャレンジ!静止画像も動画も、SVGで切り抜こう!

Webクリエイターボックスでちょこちょこ取り上げてきたSVG。今回は第四弾!SVGを使ったクリッピングマスクを紹介します。今までは画像に透過PNGを重ねてマスクを表現できましたが、高解像度ディスプレイに対応させたり、マスク自体に効果をつけるならSVGが便利かなーと思います。サムネイル画像にフレームをつけたり、デザインのアクセントとして使えるので、ぜひマスターしてくださいね!

SVG のクリッピングマスク基礎

1. 画像を用意

それではさっそく試してみましょう!まずは切り抜かれる画像を用意し、img タグで表示します。この時画像に mask というクラスを与えておきます。

<img class="mask" src="images/rose.jpg" alt="Rose" />

2. マスクの型を用意

Illustrator で切り抜く型を用意します。今回はハート型で切り抜きます。型ができたらハートをそのまま ⌘ + c (Windows は ctrl + c )でコピーし、エディターに貼り付けます。SVG コードがペーストできます。

もしくは、Illustrator で保存する際に表示されるダイアログで「SVG コード」ボタンをクリックしましょう。ながーいコードが表示されます。これが SVG です。

<img class="mask" src="images/rose.jpg" alt="Rose" />

<svg version="1.1" x="0px" y="0px" viewBox="0 0 340.2 306.6">
  <path
    d="M170.3,89.5c10.3-33,35.8-48.9,64.4-48.9c34.2,0,60.4,28.6,60.4,63.2c0,41.7-22.7,71.6-46,99.9c-22.4,27.1-79,62.2-79,62.2
          s-51.9-30.7-74.3-57.8c-23.3-28.3-50.7-62.5-50.7-104.3c0-35.2,27.1-63.2,60.7-63.2c28.3,0,53.6,15.9,63.8,48.9h0.3H170.3z"
  />
</svg>

このように画像の下に SVG を貼り付けます。

3. クリッピングパスとして定義

SVG コード内の path の部分を clipPath タグで囲い、クリッピングパスとして定義します。そしてその clipPath タグに svgPath という id を付与。(id は任意のもので OK!)

<img class="mask" src="images/rose.jpg" alt="Rose" />

<svg version="1.1" x="0px" y="0px" viewBox="0 0 340.2 306.6">
  <clipPath id="svgPath">
    <path
      d="M170.3,89.5c10.3-33,35.8-48.9,64.4-48.9c34.2,0,60.4,28.6,60.4,63.2c0,41.7-22.7,71.6-46,99.9c-22.4,27.1-79,62.2-79,62.2
          s-51.9-30.7-74.3-57.8c-23.3-28.3-50.7-62.5-50.7-104.3c0-35.2,27.1-63.2,60.7-63.2c28.3,0,53.6,15.9,63.8,48.9h0.3H170.3z"
    />
  </clipPath>
</svg>

※ちなみに今回はカーブや直線で描かれたハート型を使用しているので path タグが使われていますが、circle(円)、ellipse(楕円)、rect(長方形)、polygon(多角形)等、形によって囲むタグが変化します。混乱しないように ;)

4. CSS で切り抜く

あとは画像に与えていた mask クラスに clip-path プロパティーでパスの id を指定してマスクをかければ完成!Webkit 系ブラウザーにはベンダープレフィックスが必要です。

.mask {
  -webkit-clip-path: url(#svgPath);
  clip-path: url(#svgPath);
}

完成!

バラの画像をハートで切り抜けました!

応用 1:テキストで切り抜いてみよう

テキストで背景画像を切り抜く技は、CSS の background-clip: text; を使えば実装できます。

しかし、この方法では Chrome や Safari 以外のブラウザーではうまく表示されません。そこで他のブラウザーにも対応した SVG のやり方を紹介します。

<img class="mask" src="images/rose.jpg" alt="Rose" />

<svg>
  <clipPath id="svgPath">
    <text
      x="10"
      y="150"
      textLength="600"
      font-family="Knewave"
      font-size="100px"
    >
      She said YES!
    </text>
  </clipPath>
</svg>

基本的な書き方は上記ハート型のものと同じです。clipPath 内のマスクの型が path から text に変わり、text タグで表示したいテキストを囲めば OK。xy 属性でテキストの表示位置を調整します。他にもフォントや文字サイズ、フォントスタイルなんかも指定できます。

フォントや画像を変えていろいろ楽しめそう。

応用 2:動画にマスクをかけてみよう

これまで静止画像にマスクをかける方法を紹介しましたが、同様に動画も SVG でクリッピングマスクをかけられます。img タグで表示していた画像を video タグで動画にするだけ。video タグでは autoplay で自動再生、loop で繰り返し再生の指定をしておくといいでしょう。Firefox は mp4 形式に対応していないため、別に webm 形式も指定します。

<video class="mask" autoplay loop>
  <source src="videos/cloud.mp4" />
  <source src="videos/cloud.webm" />
</video>

<svg>
  <clipPath id="svgPath">
    <text
      x="5"
      y="100"
      textLength="595"
      font-family="Knewave"
      font-size="100px"
    >
      Sky is the limit
    </text>
  </clipPath>
</svg>

↑ サンプルの動画がうまく表示されない場合は、右下の「Rerun」ボタンで再度読み込むか、右上の「Edit on CODEPEN」をクリックして大画面で見てみてください!アイデア次第で様々な表現ができますね!

リンクのクリック範囲について

こちらのサンプルは、マスクをかけた画像にリンクを貼り、クリック範囲にカーソルを合わせると画像を半透明にしています。Firefox だと切り抜かれた白い部分(見えない部分)は無反応なのですが、Safari や Chrome だとどういうわけか切り抜かれた部分までクリック範囲として反応してしまいます…。

そのうちブラウザーが対応するのかな?とは思いますが、今のところ解決策としては img タグを使うのではなく、SVG の image 要素を使うといいみたいです。画像の指定は src ではなく xlink:href を使うので注意!この方法だと IE でもうまく表示されますよ。

<svg
  version="1.1"
  x="0px"
  y="0px"
  width="558.8px"
  height="346.7px"
  viewBox="0 0 558.8 346.7"
>
  <a xlink:href="http://google.com">
    <image
      class="mask"
      xlink:href="images/garden.jpg"
      x="0"
      y="0"
      width="615"
      height="406"
    />
  </a>

  <clipPath id="svgPath">
    <path .... />
  </clipPath>
</svg>

白い部分はカーソルを合わせても反応しなくなりました。


静止画像だけでなく GIF アニメや動画でもマスクをかけられるので、様々なデザインのアクセントとして活躍しそうな SVG クリッピングマスク。みなさんならどんなデザインに使ってみますか?

参考記事:Clipping in CSS and SVG – The clip-path Property and clipPath Element