質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Q&A

解決済

1回答

2225閲覧

二つの同じSVGをHTMLへ埋め込み動かしたいです。

laki

総合スコア16

SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

0グッド

0クリップ

投稿2017/09/17 15:22

SVG画像初心者です。

ネットのサンブルを参考に、Snap.svgを使いモーフィングアニメーションを作りました。

サンプルは1個のアニメーションですが、同時に2個のアニメーションを動かしたいのです。
同じものをコピペ後、idを変更してもうまくいきません。

<svg id="circle" version="1.1" xmlns="http://www.w3.org/2000/svg" width="110px" height="110px"></svg> <script type="text/javascript" src="snap.svg-min.js"></script> <script> var pathOne = 'M90.355,19.644c21.479,21.479,23.062,54.72,3.535,74.246s-52.767,17.944-74.246-3.535c-21.479-21.479-22.062-55.72-2.535-75.246S68.877-1.834,90.355,19.644z'; var pathTwo = 'M94.891,17.109c19.527,19.527,16.943,51.767-4.535,73.246c-21.479,21.479-54.72,23.062-74.246,3.535C-3.417,74.365-1.834,41.124,19.645,19.645C41.124-1.834,75.365-2.417,94.891,17.109z'; var $svg = Snap('#circle'); var $pth = $svg.path(pathOne).attr({fill:'#FCEE21'}); var isdir = false; function AnimationSvg() { if (!isdir) {$pth.animate({path:pathTwo, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); isdir = true; } else { $pth.animate({path:pathOne, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); isdir = false; } } AnimationSvg(); </script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2017/09/18 09:34

AnimationSvg()は動作しているのでしょうか。読まれていないようであれば、SVG読み込みにはそれなりにコストや時間もかかるものと思われますので、document.readyの後にAnimationSvg()をされてみてはどうでしょうか。
guest

回答1

0

ベストアンサー

問題の原因は純粋にJavaScriptの記述にあります.

あなたが記述したスクリプトにおいて, 定義した変数は全てグローバル変数です.(script要素直下にvarステートメントで宣言した変数はグローバル変数になります)このようなコードをコピペすると変数名が干渉しあってスクリプトが正しく動作しません.(あなたがcircle要素のid値を書き換えたのと同じ理由です)

さて、この問題を解決するには幾つか方法がありますが、一般的には適宜ブロックスコープやクロージャを定義して変数の有効範囲を制限します.

例を示します. ここではコード全体を匿名関数で囲み即時実行(クロージャ化)しています. こうするとコピペしても変数がクロージャで囲まれているので互いに独立して動作します.(もちろんid値は書き換える必要があります)

javascript

1//匿名関数を即時実行する 2(function(){ 3 var pathOne = '...'; 4 var pathTwo = '...'; 5 var $svg = Snap('#circle');//コピペ毎にここを書き換える 6 var $pth = $svg.path(pathOne).attr({fill:'#FCEE21'}); 7 var isdir = false; 8 9 function AnimationSvg() { 10 if (!isdir) {$pth.animate({path:pathTwo, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); 11 isdir = true; 12 } else { 13 $pth.animate({path:pathOne, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); 14 isdir = false; 15 } 16 } 17 AnimationSvg(); 18})();

これでコピペしやすいコードにはなりました.
が, コードのコピペそのものが避けるべき操作ですから, 私なら次のように処理を関数化し外からパラメータを渡せるようにします.

javascript

1//処理を繰り返すために関数化する 2function animate(id){ 3 var pathOne = '...'; 4 var pathTwo = '...'; 5 var $svg = Snap(id);//関数のパラメータを使う 6 var $pth = $svg.path(pathOne).attr({fill:'#FCEE21'}); 7 var isdir = false; 8 9 function AnimationSvg() { 10 if (!isdir) {$pth.animate({path:pathTwo, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); 11 isdir = true; 12 } else { 13 $pth.animate({path:pathOne, fill:'#FCEE21'}, 1000, mina.easeout, AnimationSvg); 14 isdir = false; 15 } 16 } 17 AnimationSvg(); 18}; 19//アニメーション対象を関数に知らせる 20animate("#circle"); 21animate("#circle2");

これでアニメーション対象が増える毎に1行コードを追加するだけで対処できます.

NOTE:これはJavaScriptの観点からの回答ですが, SVGのuse要素を用いた解決策もあります.

投稿2017/09/18 22:15

defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

laki

2017/09/18 23:49

動きました!丁寧な回答をどうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問