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

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

ただいまの
回答率

90.98%

  • HTML5

    3398questions

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

  • SVG

    66questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 164

laki

score 5

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>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2017/09/18 18:34

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

    キャンセル

回答 1

checkベストアンサー

+2

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

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

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

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

//匿名関数を即時実行する
(function(){
  var pathOne = '...';
  var pathTwo = '...';
  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();
})();


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

//処理を繰り返すために関数化する
function animate(id){
  var pathOne = '...';
  var pathTwo = '...';
  var $svg = Snap(id);//関数のパラメータを使う
  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();
};
//アニメーション対象を関数に知らせる
animate("#circle");
animate("#circle2");


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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/19 08:49

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

    キャンセル

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

  • ただいまの回答率 90.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • HTML5

    3398questions

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

  • SVG

    66questions

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