円動

Web

円グラフっぽいアニメーションを実装する

PageSpeed Insightsの円グラフみたいに円形でアニメーションできないか探したので、メモ。ググったりしていると、いい感じのウェブサイトを発見しました。以下がそうです。

【SVG不要!】CSSとJavaScriptで円を描くアニメーションを作ろう! - W&M de Asobo
SVGデータは一切使わず、CSSとJavaScriptのみで円を描くアニメーションを実装する方法をご紹介します。

JSとCSSだけで円形をアニメーションしてみる

上記に加え、イージングも効かせたかったので、またググるとこちらもいい感じのウェブサイトを発見。これをアレンジしてソースに追加してきます。

easingを計算でやってみる - Qiita
CSSアニメーションでも各種JSのライブラリでも、easingはとても簡単にできるようになりましたが、それらを使わずにJ…

HTMLは以下の構成。CSSもbodyとdivだけです。参考サイトとほぼ同じ。

<body>
 <div class="shape"></div>
</body>
  body {
    width: 100%;
    height: 100vh;
    background: #e4e4e4;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .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: 220px;
    height: 220px;
    background-color: #e4e4e4;
    clip-path: circle();
  }

JSも参考サイトとほぼ同じです。最後にイージングが効いてヌルっとした感じが出せました。

    const shape = document.querySelector(".shape")
    let angle = 0

    function drawCircle() {
      const dx = 240
      const speed = 0.05
      if (Math.ceil(angle) < dx) {
        angle += (dx - angle) * speed
        shape.style.backgroundImage = `conic-gradient(black ${angle}deg, #e4e4e4 ${angle}deg)`
        requestAnimationFrame(drawCircle)
      } else {
        console.log('Animation Finished!')
      }
    }

    requestAnimationFrame(drawCircle)

そして、ここからiPhoneのアプリで使われているみたいな線の形を角丸に出来ないかやってみるとうまくいきません。まあ、隠した円を動かすんですから、角丸には最初からなっていなければと考えが至り、別の方法を模索することにしました。それがSVGです。

JSとCSSを使ってSVGで円形アニメーションしてみる

検索するとこちらもいい感じの参考サイトが見つかりました。以下がそうです。

SVG 円の輪郭のアニメーション | キプレ - UIサンプル紹介
SVGを使って円を描いて、CSSを使った輪郭に沿ったアニメーションをするサンプルです。 SVGを使って円を描いて、輪郭に…

こちらを参考にやっていく中で、stroke-dashoffsetでコントロールしているのを見て、どっかで見た記憶がありました。そうだ、animejsだ。そして、animejsでやってみるとかなり楽ちんでできたんです。イージングも思いのままで、これは便利だと思いました。上記サイトの骨組みを使いつつ、組み上がったのがこちら。stroke-linecap=”round”にすることで角丸に変更できました。.svgでスタート位置が90度から始まっていたのをtransform0度の位置に変更しています。

<body>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 110 110" class="svg">
    <g class="lines" fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-width="1">
      <circle cx="55" cy="55" r="50" class="circle" />
    </g>
  </svg>
</body>
  .svg{
    display: block;
    width: 200px;
    margin: 40px;
    transform: rotate(-90deg);
  }
  .circle{
    fill: none;
    stroke: rgb(94, 29, 72);
    stroke-width: 8px;
    stroke-dasharray: 314;
  }

strokeDashoffset260のところを0にすると360度の円を描きます。線を隠す長さを入れてあげれば良い感じです。

anime({
 targets: '.circle',
 strokeDashoffset: [anime.setDashoffset, 260],
 easing: 'easeOutBounce',
 duration: 1500,
});

こんな簡単にできるとは思っても見ませんでした。

コメント