conic-gradientとclip-pathで扇形を作る
円を描くアニメーションを作る準備段階として、まずはCSSで扇形を作っていきたいと思います。
直線や四角形をCSSで表現する場合は、width + height + borderやbackground-colorで簡単にできますが、円や扇形は一筋縄ではいきません。
CSSで扇形を表現するには、background-imageプロパティの値の一つであるconic-gradientと、要素を特定の形にクリップするclip-pathを使うとうまくいきます。
conic-gradientは本来、時計回りのグラデーション背景を表現するためのものですが、グラデーションにしないことで要素の一部分だけ背景色をつけるということも可能です。
下は、div要素の0〜45度(deg)の部分だけ黒くして、その他の部分は白にした例です。
<div class="shape"></div>
.shape {
width: 250px;
height: 250px;
background-image: conic-gradient(black 45deg, white 45deg);
}
要素の一部分(45°の範囲)のみ黒の背景色にすることができましたが、これではまだ扇形にはなっていませんね。
そこで次に、clip-path: circle()を使って要素を円形にクリップし、黒色の部分を扇形にしてみたいと思います。
.shape {
width: 250px;
height: 250px;
background-image: conic-gradient(black 45deg, white 45deg);
clip-path: circle();
}
これで黒い部分を扇形にすることができました!
clip-pathでは、円形の他にも様々な形に要素を切り抜くことができますが、単に円形に切り抜きたい場合はサンプルコードのようにcircle()でOKです。
この状態で、要素の中心にもう一つ一回り小さな円形の図形を重ねて黒の扇形の中心を隠すと、扇形を円周のように見せることができます。
.shape {
width: 250px;
height: 250px;
background-image: conic-gradient(black 45deg, white 45deg);
clip-path: circle();
display: grid;
place-items: center;
}
.shape::before {
content: "";
width: 200px;
height: 200px;
background-color: white;
clip-path: circle();
}
あとは、conic-gradientの角度を変更することで円が描かれるアニメーションを表現できます。
POINT!
- ・conic-gradientで要素を時計回りのグラデーションにできる!
- ・グラデーションにせず、色をくっきりと分けることも可能!
- ・clip-path:circle()で、要素を円形に切り抜くことで扇形を作れる!
requestAnimationFrame()でアニメーション
widthやtransformの値を変化させるだけであれば、animationプロパティを使ったCSSアニメーションで簡単にできますが、中にはCSSアニメーションではうまくアニメーションできない場合もあります。
今回のconic-gradient()も、CSSアニメーションではうまくいかないので、JavaScriptでCSSの値を変化させていく必要があります。
CSSの値を徐々に変化させるにあたり、setInterval()を使って一定時間おきに処理を行っても良いのですが、今回はrequestAnimationFrame()メソッドを使ってアニメーションさせてみたいと思います。
requestAnimationFrame()は、ブラウザが画面を更新するタイミングでアニメーションできるので、より滑らかで効率的なアニメーションを実現できます。
requestAnimationFrame()は引数にコールバック関数を取り、ブラウザが次の描画を行う際に指定したコールバック関数を実行します。
つまり、アニメーションの処理を行う関数の中で、requestAnimationFrame()を呼び出す必要があるということになります。
下は、requestAnimationFrame()を使ってconic-gradient()の角度の数値を徐々に増やしていくことで、円が描かれるようにアニメーションさせた例です。
<div class="shape"></div>
.shape {
width: 250px;
height: 250px;
background-image: conic-gradient(black 0deg, white 0deg);
clip-path: circle();
display: grid;
place-items: center;
}
.shape::before {
content: "";
width: 200px;
height: 200px;
background-color: white;
clip-path: circle();
}
const shape = document.querySelector(".shape");
//角度の初期状態(0°)
let angle = 0;
function drawCircle() {
//角度が365°未満のとき
if( angle < 365 ) {
//角度を2°ずつ増やす
angle += 2;
//角度をconic-gradientの角度に代入
shape.style.backgroundImage = `conic-gradient(black ${angle}deg, white ${angle}deg)`;
//requestAnimationFrameを再度呼び出す
requestAnimationFrame(drawCircle);
} else {
console.log("アニメーションが終了しました");
}
}
//アニメーションを開始
requestAnimationFrame(drawCircle);
requestAnimationFrame()で円を描くアニメーションを作ることができましたね!
サンプルでは2°ずつ角度を増やしていますが、この数値を増やすとより速く円が描かれるアニメーションになります。
冒頭で紹介したように、スタートボタンやリセットボタンを追加すると、ユーザーの任意のタイミングでアニメーションを行わせることもできます。
WordPressではセキュリティ対策としてSVGデータをアップロードできないようになっているのですが、今回紹介した方法であればSVGを使わないので、WordPressで作られたサイトでも導入しやすいかと思います。
POINT!
- ・CSSアニメーションではうまくアニメーションできない場合、JavaScriptでアニメーションさせよう!
- ・滑らかなアニメーションを表現したい場合は、requestAnimationFrame()がおすすめ!
- ・requestAnimationFrame()の引数には、アニメーション処理を行う関数を指定しよう!