サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【SVG不要!】CSSとJavaScriptで円を描くアニメーションを作ろう!

【SVG不要!】CSSとJavaScriptで円を描くアニメーションを作ろう!

この記事にはプロモーションが含まれています。

直線が引かれるアニメーションは比較的簡単に実装できるのですが、直線ではなく曲線…たとえば円を描くようなアニメーションは意外と面倒くさいです。

円を描くアニメーションは、SVGデータを使って破線を伸ばしていく方法もあるのですが、SVGのデータを用意するのってちょっと面倒くさいですよね。

ということで今回は、CSSとJavaScriptのみで円を描くアニメーションを作ってみたいと思います!

完成のイメージは下のようになります。(Startボタンをクリックするとアニメーションが開始されます)

円を描くアニメーションは、データの読み込み(Loading)の進行状況を表したい時や、正解・完了を表したい時などに便利です。

アニメーションをマスターして、Web制作やアプリ制作の表現の幅を広げていきましょう!

この記事を読むことで分かること
  • ・conic-gradientとclip-pathで扇形を作る方法
  • ・requestAnimationFrame()でアニメーションさせる方法
  • ・これらを組み合わせて、円を描くアニメーションを作る方法

– 目次 –

conic-gradientとclip-pathで扇形を作る

円を描くアニメーションを作る準備段階として、まずはCSSで扇形を作っていきたいと思います。

直線や四角形をCSSで表現する場合は、width + height + borderやbackground-colorで簡単にできますが、円や扇形は一筋縄ではいきません。

CSSで扇形を表現するには、background-imageプロパティの値の一つであるconic-gradientと、要素を特定の形にクリップするclip-pathを使うとうまくいきます。

conic-gradientは本来、時計回りのグラデーション背景を表現するためのものですが、グラデーションにしないことで要素の一部分だけ背景色をつけるということも可能です。

下は、div要素の0〜45度(deg)の部分だけ黒くして、その他の部分は白にした例です。

HTML

<div class="shape"></div>

CSS

.shape {
    width: 250px;
    height: 250px;
    background-image: conic-gradient(black 45deg, white 45deg);
}

表示結果

要素の一部分(45°の範囲)のみ黒の背景色にすることができましたが、これではまだ扇形にはなっていませんね。

そこで次に、clip-path: circle()を使って要素を円形にクリップし、黒色の部分を扇形にしてみたいと思います。

CSS

.shape {
    width: 250px;
    height: 250px;
    background-image: conic-gradient(black 45deg, white 45deg);
    clip-path: circle();
}

表示結果

これで黒い部分を扇形にすることができました!

clip-pathでは、円形の他にも様々な形に要素を切り抜くことができますが、単に円形に切り抜きたい場合はサンプルコードのようにcircle()でOKです。

この状態で、要素の中心にもう一つ一回り小さな円形の図形を重ねて黒の扇形の中心を隠すと、扇形を円周のように見せることができます。

CSS

.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!
  1. ・conic-gradientで要素を時計回りのグラデーションにできる!
  2. ・グラデーションにせず、色をくっきりと分けることも可能!
  3. ・clip-path:circle()で、要素を円形に切り抜くことで扇形を作れる!

requestAnimationFrame()でアニメーション

widthやtransformの値を変化させるだけであれば、animationプロパティを使ったCSSアニメーションで簡単にできますが、中にはCSSアニメーションではうまくアニメーションできない場合もあります。

今回のconic-gradient()も、CSSアニメーションではうまくいかないので、JavaScriptでCSSの値を変化させていく必要があります。

CSSの値を徐々に変化させるにあたり、setInterval()を使って一定時間おきに処理を行っても良いのですが、今回はrequestAnimationFrame()メソッドを使ってアニメーションさせてみたいと思います。

requestAnimationFrame()は、ブラウザが画面を更新するタイミングでアニメーションできるので、より滑らかで効率的なアニメーションを実現できます。

requestAnimationFrame()は引数にコールバック関数を取り、ブラウザが次の描画を行う際に指定したコールバック関数を実行します。

つまり、アニメーションの処理を行う関数の中で、requestAnimationFrame()を呼び出す必要があるということになります。

下は、requestAnimationFrame()を使ってconic-gradient()の角度の数値を徐々に増やしていくことで、円が描かれるようにアニメーションさせた例です。

HTML

<div class="shape"></div>

CSS

.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();
}

JavaScript

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!
  1. ・CSSアニメーションではうまくアニメーションできない場合、JavaScriptでアニメーションさせよう!
  2. ・滑らかなアニメーションを表現したい場合は、requestAnimationFrame()がおすすめ!
  3. ・requestAnimationFrame()の引数には、アニメーション処理を行う関数を指定しよう!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン