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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1599閲覧

svgアニメーション 同じページ内に同じ効果・図形違いで複数設置したいがひとつしか動作しない

chibiyuko_0124

総合スコア18

SVG

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/02/26 04:57

編集2020/02/27 01:16

お世話になっております。
snap.svg.jsを使ってsvgアニメーションを複数実装したいのですがうまく動作せず困っております。
かなり初歩的な問題かと思うのですが、自分の知識では解決できず・・・
ご助言いただけますと幸いです。

■やりたいこと
・snap.svg.jsを使ったsvgアニメーション(2種類のパスをゆっくり動かしてぐにょぐにょ動かす)
・ループさせる
・同じページに図形違いで複数設置。効果は全く同じ

■事象
・ひとつだけなら正常に動くが、パスを追加するとループせず1回で終わってしまう(jsがうまく読み込まれていないようです)

HTML

1 2<svg id="sample01" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" 3 y="0px" viewBox="0 0 625.73 823.29" enable-background="new 0 0 625.73 823.29" xml:space="preserve"> 4<path fill-rule="evenodd" clip-rule="evenodd" fill="#000" d="M275.7.53C426.33,17,506.42,141.82,571,246.78c98.44,160-143.65,206-141,325.72,1.33,59.85,89.29,159.78,21.28,232.78C402.06,858.11,306.22,859.45,281,866.47-203.83,940.65,85.38,348.36,87.57,79.23,72.26,7.62,232-2.76,275.7.53Z"/> 5</svg> 6 7<svg id="sample02" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" 8 y="0px" viewBox="0 0 568.6 858.94" enable-background="new 0 0 568.6 858.94" xml:space="preserve"> 9<path fill-rule="evenodd" clip-rule="evenodd" fill="#000" d="M310.84,13.68C239.84,78.22,215.4,89,181.47,88.94c-121.1,0-208,117.35-174.07,233.62C24.27,380.41,48.25,436,64,494.19c20.22,74.94,15.44,155,49.78,226.25,41,97.09,132.37,99.24,221.46,79.41,45.08.54,92.35,8,134.79-11.21V31.72C418.08,3.67,360.36-13.51,310.84,13.68Z"/> 10</svg>

Javascript

1var $svg01 = Snap( '#sample01 path' ); 2var path01 = [ 3 'M251.06,41.43c150.64,16.47,99,178,200.85,247.34C600.37,358.93,701.57,571.82,552.37,624c-55.15,23.28-33.08,58.68-101.09,131.68C402.06,808.55,306.22,809.9,281,816.91-203.83,891.1,85.38,298.81,87.57,29.68,72.26-41.94,207.4,38.14,251.06,41.43Z', //パス1 4 'M275.7.53C426.33,17,506.42,141.82,571,246.78c98.44,160-143.65,206-141,325.72,1.33,59.85,89.29,159.78,21.28,232.78C402.06,858.11,306.22,859.45,281,866.47-203.83,940.65,85.38,348.36,87.57,79.23,72.26,7.62,232-2.76,275.7.53Z', //パス2 5]; 6var $svg02 = Snap( '#sample02 path' ); 7var path02 = [ 8 'M447.49,59.1c-71,64.54-85.13-30.11-167.41,6.2C170,113.88,250.63,313.1,106,298.92,46,293-13.15,412.35,2.56,470.55,22.79,545.49,237,625.51,271.33,696.8c41,97.09,73.39,179,162.48,159.16,45.08.53,92.35-71.73,134.79-91V8.07C516.69-20,497,31.91,447.49,59.1Z', //パス1 9 'M310.84,13.68C239.84,78.22,215.4,89,181.47,88.94c-121.1,0-208,117.35-174.07,233.62C24.27,380.41,48.25,436,64,494.19c20.22,74.94,15.44,155,49.78,226.25,41,97.09,132.37,99.24,221.46,79.41,45.08.54,92.35,8,134.79-11.21V31.72C418.08,3.67,360.36-13.51,310.84,13.68Z', //パス2 10]; 11var indexPath = 0; 12var DURATION = 1000; 13 14function playAnimation() { 15 if (indexPath === 0) { 16 $svg01.animate( 17 {d: path01[0] }, DURATION, playAnimation ); 18 $svg02.animate( 19 {d: path02[0] }, DURATION, playAnimation ); 20 indexPath = 1; 21 } 22 else { 23 $svg01.animate( 24 {d: path01[1] }, DURATION, playAnimation ); 25 $svg02.animate( 26 {d: path02[1] }, DURATION, playAnimation ); 27 indexPath = 0; 28 } 29 } 30playAnimation();

上記のplayAnimation内の$svg02.animateを消せば$svg01は正常に動作します。

■参考サイト
https://qiita.com/seito2014/items/07908cb732a62b40fd72

よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

SVG の path が正しい前提で回答します。

パスを追加してからアニメーションが動かなくなったのは、両方の SVG アニメーションが終わってから同じ関数playAnimationをコールバックで呼んでいるからです。
それぞれのアニメーションが終わる際に playAnimation が実行されているので、indexPath の値が連続で更新されて、アニメーションが止まっているように見えてしまっています。

修正するとしたら、playAnimation をどちらかの SVG アニメーションが終わったときのみ呼び出せばいいと思います。

js

1function playAnimation() { 2 if (indexPath === 0) { 3 // svg01のアニメーションが終わったときのみ次のアニメーションを実行する 4 $svg01.animate({ d: path01[0] }, DURATION, playAnimation); 5 // svg02はアニメーションの制御に関与しない 6 $svg02.animate({ d: path02[0] }, DURATION); 7 indexPath = 1; 8 } else { 9 $svg01.animate({ d: path01[1] }, DURATION, playAnimation); 10 $svg02.animate({ d: path02[1] }, DURATION); 11 indexPath = 0; 12 } 13}

ただ、このやり方は 1つの関数で複数の SVG アニメーションの制御をしようとしているので、今回のようにバグが起こったときに原因がわかりにくいですし、SVG アニメーションが増える度にこの関数が膨らんでしまいます。

拡張性や保守性を考えると、それぞれの SVG アニメーションごとに関数を分ける方法も検討されるといいと思います。
関数を分けておけば、それぞれの SVG アニメーションで path の数が変わった場合や、duration を変えたい場合も個別に対応しやすいです。(もちろん揃えることもできます)

js

1// svg01用のアニメーション関数 2function playAnimation1(index) { 3 $svg01.animate({ d: path01[index] }, DURATION, function() { 4 playAnimation1(++index % 2); // pathを切り替えるために、0, 1 を交互に出力する 5 }); 6} 7 8// svg02用のアニメーション関数 9function playAnimation2(index) { 10 $svg02.animate({ d: path02[index] }, DURATION, function() { 11 playAnimation2(++index % 2); 12 }); 13} 14 15// アニメーション実行 16// 最初にレンダリングするpathのindexを引数に渡します 17playAnimation1(0); 18playAnimation2(0);

動くサンプルを置いておきますので、よろしければ参考にしてください。
サンプルコード

投稿2020/02/27 11:12

編集2020/02/27 11:13
shgtkshruch

総合スコア665

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

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

chibiyuko_0124

2020/02/27 23:55

shgtkshruch様 ご丁寧に解説していただきありがとうございます。 こちらの書き方で無事解決しました。 ありがとうございました。
guest

0

自分の知識では解決できず・・・

ご助言いただけますと幸いです

javascript 内の配列変数 path01path02 に正しい d属性のフォーマットを与えてください。

ご質問の SVG は path[d] の値が間違っています。

  1. path要素のd属性について正しいフォーマットを作る:SVG 1.1仕様(日本語訳)> 8 Path
  2. オーサリングソフトの出力をそのまま使う(こちらが、手っ取り早い)

Snapsvg.js Document の animate() の第一引数に与えるオブジェクトは path 要素の属性になります。

d 属性の値を正しく記述することがSVG利用の絶対条件です。


ご質問のSVG のコードを それぞれ、 sample01.svg, sample02.svg としてブラウザに投げた結果:

Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "A-01".
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "B-01".

ご参考にされているページにおいても 2. の方法で出力した SVG から、path[d] の値を
JavaScript の変数 path に与え、正しいフォーマットを使用しています。

javascript

1var $svg = Snap( '#svg path' ); //動かしたいpath要素 2var path = 'M22,62c0,0,68-52,156-46s100,34,196,34S512,7,566,15.5S740,18,740,102s-58,152-28,182s-217.2,52-321.6,0S110,356,52,306s8-920-152S8,142,22,62z'; //アニメーション後のパス 3 4$svg.animate({d: path }, 3000 ); 5//要素.animate({d: 移動後のパス }, 'アニメーション時間' );

追記)
SVGに関して、細かく纏められている方のページです。

「Snap.svgの使い方 まとめ」は v0.3.0 当時の内容ですが(現行:v0.5.1)、「アニメーションの項目」は参考になると思います。
ご質問では、単一のPATH要素を同時にアニメーションするコードになっているため(コールバック関数がほぼ同じタイミングで2回実行されているため)、フラグとして扱う変数 indexPath が意図した通りに機能していないように思います。
SetSnap といったオブジェクトを作成し、「複数要素を同時にアニメーションさせる」方法を試してみてはどうでしょうか。

投稿2020/02/26 10:10

編集2020/02/27 02:59
AkitoshiManabe

総合スコア5432

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

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

chibiyuko_0124

2020/02/27 01:10

AkitoshiManabe様 ご助言いただきありがとうございます。 >javascript 内の配列変数 path01、path02 に正しい d属性のフォーマットを与えてください。 上記では「A-01」といった書き方をしておりますが投稿用のダミーで、実際は「M22,62c0,0,68-52...」といったパスの値を入れております。(投稿を直しますね) if (indexPath === 0) {}内の処理はうまくいくのですが、その後のelse {}が読み込まれず止まってしまう状況です。 見当違いな返信をしておりましたら申し訳ありません。
chibiyuko_0124

2020/02/28 00:00

AkitoshiManabe様 参考サイトを教えていただきありがとうございます。 デモを見ながら試していたところshgtkshruch様がコードをコメントしてくださりそちらで動きました。 snap.svgは今後も使用したいので、引き続き勉強いたします。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問