Snap.svgの基本的な使い方
2019-05-30
目次
動機
画像のフレ ームなどをもっと自由に動かしてみたいと思い SVG に手を出しました。 Snap.svgなどのライブラリを使えば比較的簡単にアニメーションを実装することができました。
完成品
まずはじめに、今回説明する内容の完成品です。
コード
See the Pen SnapFrame01 by daichi (@da10410) on CodePen.
プレビュー
See the Pen SnapFrame01 by daichi (@da10410) on CodePen.
SVG を作成する
まずはフレームとして使 用する SVG を作成します。 illustrator などがあれば理想ですが、無ければ代替となる何かを使用しましょう。 私の場合は『 Vector 』というオンライン上で SVG を 作成することができるツールを使用して作成しました。
動く前の SVG と、動いた後の SVG の 2 種類作成してください。また、 動く前と後のアンカーポイントの数は、同一にしておくと後々複雑な SVG を扱う際などに楽になります。
今回作成した SVG のイメージは下記の様なものを右上用と左下用のそれぞれ作成したので 計4枚になります。
Before
After
ベジェ曲線の描き方などは、使用するツールによって異なるので今回は省略させていただきます。
HTML
CodePen の例では Pug を使用していますが、分かりやすくするために HTML にコンパイルしたもので解説を行います。 また、例は CodePen の JS の設定で下記 CDN を読み込んでいます。実際に実装する場合には任意の個所で 下記の CDN を読み込むようにしてください。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<div class="btn">BTN</div>
<div class="img-section">
<div class="header">Test</div>
<div class="img-box">
<div class="img-ttl">dummy image</div>
<div class="img-dummy"></div>
<div class="img-frame">
<svg
class="frame"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="none"
viewBox="0 0 640 640"
>
<defs>
<path
class="bottom-wave"
id="cBBFTBwXK"
d="M340 264.74C233.33 158.07 120 69.82 0 0L0 640L640 640C546.67 496.49 446.67 371.4 340 264.74Z"
></path>
<path
class="top-wave"
id="abb2YnZoD"
d="M300 340C406.67 446.67 520 546.67 640 640L640 0L0 0C93.33 120 193.33 233.33 300 340Z"
></path>
</defs>
<g>
<g>
<g>
<use
xlink:href="#cBBFTBwXK"
opacity="1"
fill="#dfe6e9"
fill-opacity="1"
></use>
</g>
<g>
<use
xlink:href="#abb2YnZoD"
opacity="1"
fill="#dfe6e9"
fill-opacity="1"
></use>
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
作成した SVG ファイルを「 sublimeText 」や「 Visual Stadio Code 」などの テキストエディタで開きましょう。すると、下記の様な html 文で表示されるかと思います。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 640 640"
width="640"
height="640"
>
<defs>
<path
d="M167.52 45.18L283.83 45.18L283.83 145.89L167.52 145.89L167.52 45.18Z"
id="i25ErMfTfi"
></path>
</defs>
<g>
<g>
<g>
<use
xlink:href="#i25ErMfTfi"
opacity="1"
fill="#c1ecad"
fill-opacity="1"
></use>
</g>
</g>
</g>
</svg>
この
<svg>
<div class="img-frame">
また SVG を同一 svg タグ内で 2 枚使用する場合、 2 枚目の
<def>
<path>
<def>
CSS
今回は割愛します。
JS
続いて js の説明です。
const $topw = Snap(".top-wave")
const $btmw = Snap(".bottom-wave")
let states = "close"
$(".btn").on("click", function () {
if (states === "close") {
$btmw.animate(
{
d:
"M40 600C20 580 6.67 553.33 0 520L0 640L120 640C86.67 633.33 60 620 40 600Z",
},
350,
mina.easein
)
$topw.animate(
{
d:
"M600 40C620 60 633.33 86.67 640 120L640 0L520 0C553.33 6.67 580 20 600 40Z",
},
350,
mina.easein
)
states = "open"
} else {
$btmw.animate(
{
d:
"M340 264.74C233.33 158.07 120 69.82 0 0L0 640L640 640C546.67 496.49 446.67 371.4 340 264.74Z",
},
350,
mina.easein
)
$topw.animate(
{
d:
"M300 340C406.67 446.67 520 546.67 640 640L640 0L0 0C93.33 120 193.33 233.33 300 340Z",
},
350,
mina.easein
)
states = "close"
}
})
path の指定
まず、操作する
<path>
Snap
const $topw = Snap(".top-wave")
const $btmw = Snap(".bottom-wave")
アニメーション実行
ボタンをクリックした際にアニメーションが実行されるようにします。 現在、SVG がどのような状態になっているかを
states
アニメーションは、先ほど取得したパスに
animate
<path
d="~~~~"
=
:
(変更するパス).animate({(d:"~~~~")},アニメーション秒数, イージング);
これで SVG のアニメーションを実行する事ができます。
まとめ
Snap.svg を使用すると SVG のアニメーションを Jquery と同じような感覚で簡単に実装する事ができます。 ループで実行することもできるので、フレームをずっとうねうねさせることも可能です。 CSS のみでは出来ない複雑なうごきも SVG を作成する事が得意であれば簡単に実装できるので デザインの幅が広がると感じました。