雲隠れの術

要素を隠すことができるmaskプロパティを使って、雲に隠れたり現れたりする「雲隠れの術」の作り方と、マスクする雲模様の作り方も合わせてご紹介します:)

雲隠れするパンちゃん
ドロンッ

マスクするCSS

雲で隠すのには、要素をマスキングすることができるmaskプロパティを使います。
maskプロパティはmask関連のプロパティを一括指定するためのプロパティで、mask関連のプロパティは以下の通り。

mask-imageマスク・イメージ
マスクする型となる画像を指定する。-webkit-mask-image
none / url() / linear-gradient() / image()
mask-positionマスク・ポジション
要素内のマスクの揃え位置を指定する。-webkit-mask-position
center / top / right / bottom / left / 数値
mask-sizeマスク・サイズ
マスク画像の使用サイズを指定する。-webkit-mask-size
auto / cover / contain / サイズ
mask-repeatマスク・リピート
マスク画像の繰り返す方向、繰り返し方を指定する。-webkit-mask-repeat
repeat / repeat-x / repeat-y / space / round / no-repeat
mask-clipマスク・クリップ
マスクが反映される領域を指定する。-webkit-mask-clip
margin-boxは未対応(2023.4現在)
border-box / padding-box / content-box / margin-box / fill-box / stroke-box / view-box / no-clip
mask-originマスク・オリジン
マスクの原点を指定する。-webkit-mask-origin
margin-boxは未対応(2023.4現在)
border-box / padding-box / content-box / margin-box / fill-box / stroke-box / view-box
mask-modeマスク・モード
マスクする画像の輝度透明度のどちらでマスクするか指定する。-webkit-mask-mode
Chromeは未対応(指定を無視して常にalphaになる)、Safariは不思議(luminanceを適用すると画像が4分の1しか表示されない)(2023.4現在)
match-source / alpha / luminance
mask-compositeマスク・コンポジット
複数のマスク画像を指定した際のマスクの重なり方を指定する。-webkit-mask-composite
ChromeはWebKit独自仕様の違う値(source-over / source-out / source-in / xor)で対応カバーできる(2023.4現在)
add / subtract / intersect / exclude

2023.4現在、Chromeでも標準仕様を適用するために、-webkit-プレフィックスを付けたプロパティも合わせて指定すること。

雲型にマスクする

たくさんあるけれど、雲隠れに使うプロパティはmask-imagemask-positionmask-sizemask-repeatの4つ。maskプロパティで一括指定すると下記のようになります。backgroundプロパティと同じ書き方ですね;)

figure {
	-webkit-mask: url(../img/cloud.webp) center / 100% auto no-repeat;
	mask: url(../img/cloud.webp) center / 100% auto no-repeat;
}
画像をマスクしたサンプル

これで、「雲以外の部分が透過している画像(cloud.webp)」の不透明部分カタチに、「要素に対して中央centerに、横幅いっぱいの大きさ100% autoで、繰り返さずno-repeatに置いて、重なった部分」をマスクしている状態になります(下図)

マスクされた要素は「画像の不透明部分の型」にくり抜かれる

maskプロパティについて詳しくは下記ページを参照のこと。

雲型をアニメする

transitionプロパティを指定すれば、値の変化がスムーズになります。下サンプルは、画像にマウスオーバー(タップ)すると、mask-positionプロパティの値(マスクの位置)と、mask-sizeプロパティの値(マスクの大きさ)が、それぞれスムーズに切り替わるよう指定しています。

-webkit-プレフィックス付きのmaskも併せて指定するのも忘れずに。

.position {
	-webkit-mask: url(../img/cloud.webp) center / 100% auto no-repeat;
	mask: url(../img/cloud.webp) center / 100% auto no-repeat;
	transition: -webkit-mask-position 1s, mask-position 1s;
}
.position:hover {
	-webkit-mask-position: center bottom;
	mask-position: center bottom;
}
maskプロパティをアニメーションするための指定(抜粋)
値がスムーズに切り替わるサンプル

マスクの位置と大きさをいっぺんに変化させるとこんな感じ。雲隠れしそうな感じになってきましたね:D

figure {
	-webkit-mask: url(../img/cloud.webp) center / 100% auto no-repeat;
	mask: url(../img/cloud.webp) center / 100% auto no-repeat;
	transition: -webkit-mask 1s, mask 1s;
}
figure:hover {
	-webkit-mask-position: center bottom;
	mask-position: center bottom;
	-webkit-mask-size: 150% auto;
	mask-size: 150% auto;
}
マスクの位置と大きさがスムーズに変化するサンプル

雲隠れのCSS

さて、雲隠れのCSSを作ってゆきます:)
要素をマスキングすることができるmaskプロパティで要素を雲模様に隠して、値の変化をtransitionプロパティでスムーズにすれば、「雲隠れの術」の出来上がりです;D

雲隠れの要素の構造

上サンプルの雲の動きだけだとちょっともの寂しいので、雲をもうふたつ重ねて、三層の雲マスクを別々に動かすことにします。HTMLは下ソースコードの通り、figure要素の中にimg要素が入っている、というシンプルな構造。

<figure class="dolon">
	<img src="pan.svg" alt="雲隠れするパンちゃん" width="380" height="380">
</figure>

そこに、CSSで、figure要素の::before擬似要素を作り、背景色で塗りつぶして、img要素の下に配置します。

.dolon {
	position: relative;
	background: #55396808;
}
.dolon::before {
	content: "";
	z-index: -1;
	position: absolute;
	inset: 0;
	background: #553968;
}
.dolon img {
	opacity: .8;
	mix-blend-mode: lighten;
}

この、figure要素とimg要素と::before擬似要素のみっつに、それぞれ雲マスクを適用します。

雲隠れの要素の構造

雲隠れの雲マスク

2種類の雲模様を用意しました。
ひとつは、img要素(パンちゃん)と::before擬似要素(色ベタ)を隠す用の「隠れ雲(cloud.webp)」。もうひとつは、figure要素(全体)を隠す「ドロン雲(dolon.webp)」です。(※画像の作り方は後述。)

隠れ雲(左)とドロン雲(右)

マスクの指定は、それぞれ下ソースコードの通り。いったんmaskプロパティで、3つともにマスクの指定をして、あと個別に、マスク具合をバラけさせる指定をします。
まずは隠す前のマスクの指定。
いったん、要素に対して、縦横1.5倍150%の範囲を、中央上揃えの位置でマスクしています。マスクに使う画像の上部3分の2くらいが不透明になっているので、その不透明部分だけが要素を覆うようにマスクすることで、ちょうど隠れてない状態にしてるってこと;)

.dolon,
.dolon::before,
.dolon img {
	-webkit-mask: url(../img/cloud.webp) center top / 150% 150% no-repeat;
	mask: url(../img/cloud.webp) center top / 150% 150% no-repeat;
}
隠す前のマスクの指定(一旦)
img要素がぎりぎりマスクされないくらいの大きさ

個別に、figure要素だけは「ドロン雲」に変えて、::before擬似要素とimg要素は、マスクの位置を左右に振り分けています。

.dolon {
	-webkit-mask-image: url(../img/dolon.webp);
	mask-image: url(../img/dolon.webp);
}
.dolon::before {
	-webkit-mask-position: rignt top;
	mask-position: rignt top;
}
.dolon img {
	-webkit-mask-position: left top;
	mask-position: left top;
}
マスク具合をバラけさせる指定
隠す前のサンプル

隠す前なので隠れていませんが、上サンプル下段のmask-positionの上下揃え位置をbottomにしているものを見ると、マスク具合の違いがわかりますね:D


そして、マウスオーバーした時に、マスクで隠すように指定します。
マスクの位置を「上方向」に移動させ、マスクの大きさを、横幅だけ150%から200%に伸ばすことで、横に広がりながら上方向に移動する動きになります。
img要素のマスクは、左揃えから右揃えに変化する、ということは、「左上(↖︎)方向」へ移動することになります。::before擬似要素のマスクは逆に、「右上(↗︎)方向」へ移動させます。

.dolon:hover,
.dolon:hover::before,
.dolon:hover img {
	-webkit-mask-position: center 250%;
	mask-position: center 250%;
	-webkit-mask-size: 200% 150%;
	mask-size: 200% 150%;
}
.dolon:hover img {
	-webkit-mask-position: rignt 250%;
	mask-position: rignt 250%;
}
.dolon:hover::before {
	-webkit-mask-position: left 250%;
	mask-position: left 250%;
}
隠すマスクの指定
隠れゆく経過がわかるサンプル

実際には:hover擬似クラスで指定するのだけれど、上サンプルでは、隠れた後隠れ途中の状態を、個別に指定してみました。
::before擬似要素とimg要素を隠している「隠れ雲」の方は、隠れた後も隠れ切っていないですが、最終的に「ドロン雲」の方でfigure要素全体を隠してしまうので、問題ないのです;)

雲隠れに動きをつける

あとは、これにtransitionプロパティを指定して、値の変化をスムーズにすれば「雲隠れの術」です:D
下ソースコードのように指定してみました。
まずは3つともに、transitionプロパティを指定しています。
雲に隠れる時は、「出だし速くて徐々に遅くなるタイプ」のイージングcubic-bezier(.3,1,.7,1)で、雲から現れる時は、「出だしとお尻が遅いタイプ」のイージングcubic-bezier(.7,0,.3,1)になるようにしています。
それから、隠れる時は、figure要素だけ少し遅れて隠れるようにして、中身の::before要素とimg要素の雲隠れがちょっとでも見えるようにしています。逆に、現れる時は、figure要素だけは少し早めに現れるようにしています。

.dolon .mask,
.dolon .mask::before,
.dolon img {
	transition: -webkit-mask 1.2s, mask 1.2s;
	transition-timing-function: cubic-bezier(.7,0,.3,1);
}
.dolon .mask {
	transition-duration: 1s;
}
.dolon:hover .mask,
.dolon:hover .mask::before,
.dolon:hover img {
	transition-timing-function: cubic-bezier(.3,1,.7,1);
}
.dolon:hover .mask {
	transition-duration: 1.4s;
}
transitionプロパティの指定のみ抜粋
ホバー(タップ)するとドロンするパンちゃんのサンプル

figure要素と::before擬似要素とimg要素を分けて見ると、雲はこんなふうに動いています。

パーツごとのドロン具合が見れるサンプル

雲の作り方

雲の画像はPhotoshopで作ります。
カンバスはお好きなサイズで良いけれど、4000px×4000pxくらいがちょうど良いかなと思います。新規ファイルを作成したら、「cloud.psd」という名前で、良き場所に保存しておきましょう:D

4000px×4000pxの背景黒色で新規作成

下準備

まずは新規レイヤーを作成し、おもむろに「フィルター」→「描画」の雲模様 1を適用。全面が雲の模様になります(下図1枚め)
雲模様レイヤーを複製して、上の雲模様レイヤーの「描画モード」を覆い焼きカラーに変更します。明るい色と明るい色が重なったところがより明るく、コントラスト強めの印象になります(下図2枚め)
これで下準備完了!

新規レイヤーに「雲模様 1」を適用
複製して「覆い焼きカラー」で重ねる

雲を描く

雲模様と雲模様の間に新規レイヤーを作って、ここに雲を描いてゆきます。例えば、グラデーションで塗りつぶすだけでも雲っぽくなっちゃいます(下図):D

グラデーションするだけで雲っぽくなる

ここでは、figure要素全体を隠す「ドロン雲」を描いてゆくことにします。
ドロン雲は最終的に全てを覆い隠す役回りなので、ぜったいに隠れるようにしないといけません(塗り残し厳禁!)。なので、大事な部分は、最初にきっちり塗りつぶしておくと良いです。不透明でないといけないところは長方形ツール白く塗りつぶし、透明でないといけないところは楕円形ツール黒く塗りつぶしておきます(下図1枚め)
ブラシツールで、図形の“すじ”をうまく馴染ませながら、雲を描いてゆきます。不透明度50%くらいにしてポチポチしてゆくと捗ります(下図2枚め);)
消しゴムツールで消すと、元の雲模様がそのまま出るので、雲の輪郭がパキッとします。

スーパーヒーロースーパーウォーズ
絶対透明のところと絶対不透明のところ
ブラシツールや消しゴムツールで雲を描く

画像の書き出し

描き上がったら、「チャンネル」パネルの「RGB」のサムネイルを、optionキーを押しながらクリック、すると表示中の画像の白い要素だけが選択された状態になります。すかさず新規レイヤーを作って、塗りつぶしツールで、選択範囲を白く塗りつぶしたら、雲完成ー(下図1枚め)
その他のレイヤーを非表示にしてから、全レイヤーをグループ化して、グループレイヤーにレイヤーマスクを適用したらば、グループレイヤー名を「dolon.png」という名前に変更しておきます(下図2枚め)

新規レイヤーを白く塗りつぶし
グループレイヤーにしてファイル名を変更する

ファイル」→「生成」の画像アセットを実行すれば、ドロン雲の出来上がりX)
cloud-assets」というフォルダの中に「dolon.png」が書き出されるはずです。