更新 Firefox での動作について 2016.9.29
こちらで紹介している方法が、Firefoxで安定して動かないようでobjectタグでsvgを読み込むのではなく、直接svgタグを埋め込むことによって期待する動きに近づきました。
Firefoxでも動いている例はこちら
現時点ではこれだという決定打を出せていないので、解決次第、再度更新します。
概要・経緯
タイトルの通り、Illustratorから書き出したSVGをVelocity.jsで動かします。件の経緯として、運営しているサイトのロゴを動くものにしたかったのでやってみたよ
環境、バージョン
- Mac OS X El Capitan
- Adobe Illustrator CC
- jQuery 3.1.0
- Velocity.js 1.3.0
DEMO
今回用意したベクター
とりあえず適当なオーナメントを用意してみた。
ちなみにこのオーナメントは、今進めてるリニューアルのデザイン上ではこんな感じでつかってます(下の方にちょろっと)。
今回はこのオーナメントだけをアニメーションさせるよ
SVGに吐き出す
「ファイル」から、「保存(もしくは別名で保存)」を選択します
次に、保存の形式を「SVG」を選択
こんな感じで
このウィンドウで「保存」をクリックすると、各種設定画面がでます。今回は以下のように設定しています。()
「OK」を押せばSVGファイルの出来上がりです。
エディタで開いてみるとこんな感じに。
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 398 398" style="enable-background:new 0 0 398 398;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#000000;stroke-miterlimit:10;}
</style>
<path class="st0" d="M42.3,302.4c65.6-26.5,148.4-97.8,176.6-129.5l-1.1-1.1C142.4,223,77.9,252.9,49.2,249.5
c4.6-18.4,6.9-39.1,9.2-52.9c89.7,0,155.3-42.6,173.7-61l-1.1-1.1c-49.5,17.3-124.2,25.4-165.6,18.5c5.8-19.5,6.9-43.7,8.1-56.4
c108.1,34.5,170.2,13.7,208.2-1.2c-6.9-13.8-5.7-33.3,8.1-47.1c17.3-17.3,44.9-17.3,61-1.2c17.3,17.3,17.2,44.9,0,62.1
c-13.8,13.8-33.4,15-47.1,8.1c-15,38-35.7,100.1-1.2,208.2c-12.6,1.2-36.8,2.3-56.4,8.1c-8-42.6,1.2-116.2,18.5-165.6l-1.1-1.1
c-18.4,18.4-61,84-61,173.7c-13.8,2.3-34.5,4.6-52.9,9.2c-3.4-28.8,26.5-93.2,77.7-168.5l-1.2-1.2c-31.6,28.2-103,111-129.4,176.6
c-14.9,1.2-43.7,4.6-65.6,10.4C36.5,344.9,41.1,317.3,42.3,302.4z"/>
</svg>
xml宣言、コメント、styleタグを消し、idとクラス名を変えたものがこちら。消したスタイルはpathに突っ込んだ。単一のパスならばこれでおっけい。もし、モヤッとするならば最低でも以下のことはやったほうが良いかも
- xml宣言は消す(HTMLに埋め込む)
- svgタグに日本語で定義されてしまったidを英語に
<svg version="1.1" id="ornament" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 398 398" style="enable-background:new 0 0 398 398;" xml:space="preserve">
<path class="ornamentPath" d="M42.3,302.4c65.6-26.5,148.4-97.8,176.6-129.5l-1.1-1.1C142.4,223,77.9,252.9,49.2,249.5
c4.6-18.4,6.9-39.1,9.2-52.9c89.7,0,155.3-42.6,173.7-61l-1.1-1.1c-49.5,17.3-124.2,25.4-165.6,18.5c5.8-19.5,6.9-43.7,8.1-56.4
c108.1,34.5,170.2,13.7,208.2-1.2c-6.9-13.8-5.7-33.3,8.1-47.1c17.3-17.3,44.9-17.3,61-1.2c17.3,17.3,17.2,44.9,0,62.1
c-13.8,13.8-33.4,15-47.1,8.1c-15,38-35.7,100.1-1.2,208.2c-12.6,1.2-36.8,2.3-56.4,8.1c-8-42.6,1.2-116.2,18.5-165.6l-1.1-1.1
c-18.4,18.4-61,84-61,173.7c-13.8,2.3-34.5,4.6-52.9,9.2c-3.4-28.8,26.5-93.2,77.7-168.5l-1.2-1.2c-31.6,28.2-103,111-129.4,176.6
c-14.9,1.2-43.7,4.6-65.6,10.4C36.5,344.9,41.1,317.3,42.3,302.4z" style="fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#000000;stroke-miterlimit:10;"/>
</svg>
HTMLに埋め込む
今回は、objectタグを使ってみます。HTMLの用意の仕方は各々てきとーにどうぞ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>svg sample</title>
</head>
<body>
<div id="svg_area">
<object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
</div>
</body>
</html>
これをブラウザで表示するとひたすらでかいsvgが表示されるはず。
JSとCSSを用意
現時点でCSSは空っぽ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>svg sample</title>
<link rel="stylesheet" href="css/index.css">
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="js/Velocity.js"></script>
<script src="js/design.js"></script>
</head>
<body>
<div id="svg_area">
<object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
</div>
</body>
</html>
とりあえずobjectタグの高さを120pxくらいにします。
# svg_ornament {
height: 120px;
}
ちょっと不安なくらい大きかったのが随分としおらしくなった
続いてJS。このコードは velocity.jsでぐにゃぐにゃSVGを描くを参考にした。
(function($){
var SvgUtil = {
addStyle: function(paths, color, fill, strokeWidth)
{
paths.each(function(){
// getTotalLength はパスの長さを取得することができる。
// + 30 は firefox 対策だそうです
// 参考:velocity.jsでぐにゃぐにゃSVGを描く http://qiita.com/nekoneko-wanwan/items/f7bd86e41439aeaac33f
var path_length = $(this)[0].getTotalLength() + 30;
$(this).css({
'strokeDasharray': path_length,
'strokeDashoffset': path_length,
'stroke': color,
'fill': fill,
'strokeWidth': strokeWidth
});
});
}
};
$(window).on('load', function() {
var contentDocument = document.getElementById('svg_ornament').contentDocument;
var paths = $(contentDocument).find(".ornamentPath");
SvgUtil.addStyle(paths, '#584044', 'none', 1);
paths
.velocity({ strokeDashoffset : 0 }, 1000 , "linear")
.velocity({ fill: "#584044" }, 1000 , "linear");
});
}(jQuery));
velocityについての詳しいことは会社にいるベロシティおじさんにでも聞いてください。また、strokeDasharray
とstrokeDashoffset
についても会社のCSSおじさんにでも聞いてください
これで上記で示したDEMOの状態にはなります。
リンクを貼る
このsvgにリンクを貼ってみた
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>svg sample</title>
<link rel="stylesheet" href="css/index.css">
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="js/Velocity.js"></script>
<script src="js/design.js"></script>
</head>
<body>
<div id="svg_area">
<a class="svg_link" href="http://webya.in">
<object id="svg_ornament" data="images/ornament.svg" type="image/svg+xml"></object>
</a>
</div>
</body>
</html>
当然動かないわけです。動かないんだけど、CSSであっさり解決。aタグをブロック系の要素にし、オブジェクトタグにpointer-events: none
を設定するとよい。(参考:Retina対応にSVGを使う方法とリンクを張る時の注意点)
# svg_ornament {
height: 120px;
pointer-events: none;
}
.svg_link {
display: inline-block
}
参考にした記事を丸パクリした感じになっちゃったけど、jsのaddStyle
辺りは再利用出来るようにしてみた。なんか久々にフロントやってて知らないことが多かった(とくにCSSまわり)ので勉強になりましたよっと。以上、SVGでモテモテ講座でした。