SVGのラインアニメーションをIE対応させる

コーディングチームの平野です。

IE8のサポートが正式に終了したこともあり、これからSVGを使用する頻度が増えてくると思います。 本ブログでも以前CSSで簡単なSVGアニメーションを実装 という内容でSVGアニメーションについてご紹介しましたが、 個人的な勉強も兼ねて、CSSだけではSVGアニメーションが表示されないIEでの対応方法をご紹介します。

IEでのSVGのラインアニメーションについて

アニメーションの原理についてはtransitionを用いた時と同じですが、JavaScriptでstroke-dashoffsetの値を更新する場合は、

  • setTimeout()
  • requestAnimationFrame()

のどちらかを使用して対応します。

今回はrequestAnimationFrame()を用い、下記のようなラインアニメーション用のclassを作成しました。

class drawSvg {
    constructor(el) { // el = SVG Element
    this.el = el;
    this.type = el.tagName; // 'path' or 'line'
    this.currentFrame = 0;
    this.totalFrame = 60;
    this.handle = 0;
    if (this.type === 'path') {
     this.elLength = el.getTotalLength();
    }  else if (this.type === 'line') {
    this.elLength = getTotalLineLength(this.el);
    }
    this.el.style.strokeDasharray = `${this.elLength} ${this.elLength}`;
    this.el.style.strokeDashoffset = this.elLength;
    }

    draw() {
        this.el.style.opacity = 1; // stroke-linecapを使うとlinecapの部分が最初から表示されてしまうので、ここで表示させる
        this.svgAnimation();
    }

    svgAnimation() {
        const _this = this;
        const progress = this.currentFrame / this.totalFrame;
        if (progress > 1) {
            window.cancelAnimFrame(this.handle);
        } else {
            this.currentFrame++;
            this.el.style.strokeDashoffset = Math.floor(this.elLength * (1 - progress));
            this.handle = window.requestAnimFrame(function() { _this.svgAnimation(); });
        }
    }

    resetAnimation() {
        this.el.style.strokeDashoffset = this.elLength;
        this.currentFrame = 0;
    }
}

svgAnimation()がラインアニメーション実行部分になっており、frame毎にstroke-dashoffsetの値を0に近づけていく処理を書いています。

補足として、line要素の場合、getTotalLength()では要素の長さが取得できないので、下記のように専用の関数を準備して長さを取得するようにしています。

// line要素用 長さ取得関数
const getTotalLineLength = (elem) => {
    const x1 = elem.getAttributeNS(null, 'x1');
    const y1 = elem.getAttributeNS(null, 'y1');
    const x2 = elem.getAttributeNS(null, 'x2');
    const y2 = elem.getAttributeNS(null, 'y2');
    const length = Math.sqrt((x2-=x1)*x2 + (y2-=y1)*y2);
    return length;
};

上記のラインアニメーション用のclassを用い、入力した文字がラインアニメーションで表示されるようなアプリケーションを作ってみました。
Alphabet Svg Line Animation Alphabet Svg Line Animation

まとめ

CSSによるSVGラインアニメーションの実装に比べると作業量は増えてしまいますが、同じ原理を使っているので、

  • stroke-dashoffset
  • stroke-dasharray

の使い方を知っていれば理解しやすい内容かと思います。

今回のようなSVGのアニメーションによる演出は比較的簡単に実装できるので、
基本的な原理を押さえて扱えておくと何かと活用できる場面があるかと思います。

スマホアプリ制作、Web制作、UIコンサルなどのご依頼はこちら

お問い合わせ