SVGで円弧を描くアニメーションを実装する

公開日:2019-04-14
最終更新:2019-04-14
※この記事は外部サイト(https://labor.ewigleere.net/2019/04/14/svg...)からのクロス投稿です

たまに見かける、アイコンや画像の周りを円弧がぐるっと1回転するアニメーション。

これをどうにか実装できないかと考えて、なんとか形にすることができたので書き留めます。

条件としては下記。

  • SVGで円弧を描く
    • アニメーションはcss3のkeyframeアニメーションを使用
  • レスポンシブ対応
  • JavaScriptでアニメーション開始タイミング(スクロール量)を制御
    • クラス付与するとアニメーションが開始

実は今までSVGを触ったことがなかったため、今回初めてで手探りとなりました。

コード

できたコードが下記。なお、サンプルのためBootstrap4とFontAwesome利用です。

HTML

<div class="fairycircle fairycircle_address mb-5">  
    <i class="fas fa-fw fa-address-card fa-5x fairycircle_icon" aria-hidden="true"></i>  
    <div class="fairycircle_svg">  
        <svg class="fairycircle_svgImg" width="400" height="400" viewBox="0 0 400 400">  
            <circle class="fairycircle_svgCircle" cx="200" cy="200" r="195" />  
        </svg>  
    </div>  
</div>  

今回は直径400px、線の太さ10px(cssで指定)の円弧をベースにします。

上記コードでは、svgタグ内のwidth, height400を指定。viewBox(描画領域のサイズ)は幅・高さ共に0400なので0 0 400 400

円弧を描くためsvgの子要素にcircleタグ。cx, cy属性は直系の半分で200

実際の半径を指定するrですが、線の太さを加味します。今回は10pxで、中心が半径に当たるので線の太さの半分の値を直系の半分から差し引いて195です。

Scss

$main-color: #39e16b;  
$main-color2: darken($main-color, 15%);  
$main-color3: lighten($main-color, 15%);  

.fairycircle {  
    max-width: 400px; //直径  
    margin: auto;  
    position: relative;  
    &_icon {  
        position: absolute; //absoluteで重ねる  
        left: 50%; //中央寄せ  
        top: 50%;  
        transform: translate(-50%, -50%);  
        display: block;  
        &.fa { //アイコンの色  
            &-life-ring {  
                color: $main-color;  
            }  
            &-box-open {  
                color: $main-color2;  
            }  
            &-address-card {  
                color: $main-color3;  
            }  
        }  
    }  
    .fairycircle_svg { //svgの親要素にwidth: 100%を指定  
        position: relative;  
        width: 100%;  
        padding-top: 100%;  
        &Img { //svgにabsolute指定  
            position: absolute;  
            top: 0;  
            left: 0;  
            width: 100%;  
            height: 100%;  
            transform: rotate(-90deg); //3時の方向からアニメーションが開始されるので、反時計回りに90度回転させて真上からアニメーションさせる  
        }  
        &Circle { //svgの円弧  
            fill: transparent;  
            stroke-width: 10; //線の太さ  
            stroke: transparent; //クラス付与されていないときは透明にしておく  
            &.circleEffect {  
                animation: circle 3s 1 forwards; //アニメーション。クラス付与したタイミングでアニメーションを開始する  
            }  
        }  
        @keyframes circle {  
            0% { stroke-dasharray: 0 1256; } /* ceil(400 * 3.14) */  
            99.9%,to { stroke-dasharray: 1256 1256; }  
        }  
    }  
    &.fairycircle_support { //線の色を透明から変化  
        .circleEffect {  
            stroke: $main-color;  
        }  
    }  
    &.fairycircle_box {  
        .circleEffect {  
            stroke: $main-color2;  
        }  
    }  
    &.fairycircle_address {  
        .circleEffect {  
            stroke: $main-color3;  
        }  
    }  
}  

上記の通り、keyframeアニメーションで円弧を描きます。肝は

  • レスポンシブ対応
  • アイコンとSVGをposition: absolute;で重ねる
  • デフォルトの線の色は透明にしておく
  • JavaScriptでクラス付与したタイミングで以下の2つを実施
    • 線の色を適宜変更
    • keyframeアニメーション実行開始

JavaScript(jQuery)

$(function() {  
    svgAnimeTrigger()  
}  
//svgアニメーショントリガー  
const svgAnimeTrigger = function() {  
    const $svgWrapper = $(".fairycircle")  
    const vh = $(window).height()  

    $(window).on("scroll", function() {  
        let currentPos = $(window).scrollTop()  
        $svgWrapper.each(function() {  
            let position = $(this).offset().top  
            let posiVal = Math.floor(position)  
            if (currentPos > posiVal - vh) { //スクロール量が一定量に達したら  
                $(this).find(".fairycircle_svgCircle").addClass("circleEffect") //クラス付与  
            }  
        })  
    })  
}  

JavaScript(jQuery)でやることは「スクロール量を計測し、各SVGに対する閾値を越えたらクラス付与する」ことだけです。

これで、以下のように要素が見えたところまでSVGがスクロールすると円弧を描くアニメーションが実行される、という形です。

思ったよりもサクッとできて良かった。

参考

記事が少しでもいいなと思ったらクラップを送ってみよう!
22
+1
アルム=バンドのQrunch

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする