SVGアニメーションで初音ミクの一筆書き

SVGによるアニメーションの勉強メモと,作った初音ミクの一筆書きアニメーション.

アニメーションをSVGのanimateMotion要素と,CSSのanimationプロパティを使った.本当はCSS使わないでやりたかったのだけどそれだと面倒くさそうだったのでCSSも使った.

元画像は以下のサイトから持ってきた.
piapro(ピアプロ)|イラスト「一筆書きで 初音ミクを 描きました」


以下が作ったアニメーション.SVGCSSのアニメーションの同期の取り方がわからなかったので,読み込みの度にタイミングが変わってしまう.

SVGファイルを置くのに借りていたレンタルサーバーの期限が切れてしまったため、暇なとき別のところにアップロードしなおします。

SVG animateMotion要素

赤い円を移動させるのには,SVGanimateMotion要素を使った.

animateMotion要素を用いると,図形をpathで指定した任意の曲線に沿って移動させることが出来る.また,mpath要素によって以下のようにpathの参照が可能.

<path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
      stroke="lightgrey" stroke-width="2" 
      fill="none" id="theMotionPath"/>
<circle cx="10" cy="110" r="3" fill="lightgrey"  />
<circle cx="110" cy="10" r="3" fill="lightgrey"  />

<!-- Here is a red circle which will be moved along the motion path. -->
<circle cx="" cy="" r="5" fill="red">

    <!-- Define the motion path animation -->
    <animateMotion dur="6s" repeatCount="indefinite">
       <mpath xlink:href="#theMotionPath"/>
    </animateMotion>
</circle>
animateMotion - SVG | MDN

CSS animate要素

線を描いていく様子は,CSSanimate要素を使って破線の間隔を変える方法を使った.
破線の間隔が変わることで線が伸びて行っているように見えるようだ.

How SVG Line Animation Works | CSS-Tricks

CSSに以下のように描いてやるといいようだが,stroke-dasharrayやstroke-dashoffsetの値を線の長さくらいにしなくてはならないらしく少し面倒.

path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear forwards;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}

d3.jsで作成

初音ミクの座標データは画像からこつこつと抽出した.以下からダウンロード可能.
http://whoopsidaisies.site-station.net/blog/miku.csv

SVG直打ちでもよかったが,せっかくなのでd3.jsでCSVファイルを読み込んでSVGを吐き出した.

d3.csv("miku2.csv", function (data) {

    var line = d3.svg.line()
        .x(function (d) { return Math.round(d.x * 10) / 10; })
        .y(function (d) { return Math.round(d.y * 10) / 10; })
        .interpolate("linear");

    var svg = d3.select("body").append("svg").attr("width", 700).attr("height", 900);
        
    var path = svg.append("path")
        .attr({
            "d": line(data),
            "stroke": "black",
            "stroke-width": 2,
            "fill": "none",
            "id": "mikupath"
        });

    svg.append("circle")
        .attr({
            "cx": "",
            "cy": "",
            "r": "5",
            "fill": "red"
        })
        .append("animateMotion")
        .attr({
            "dur": "20s",
            "repeatCount": "indefinite"
        })
        .append("mpath")
        .attr("xlink:href", "#mikupath");
});


ソースコード全文は以下.
http://whoopsidaisies.site-station.net/blog/mikuanimation2.html


実行後のhtmlは以下.
http://whoopsidaisies.site-station.net/blog/mikuanimation.html

レンタルサーバーの期限が切れてしまったため、暇なとき別のところにアップロードしなおします。