- ベストアンサー
外部SVGファイルを指定時のJavaScript
- 外部SVGファイルを指定している場合のJavaScriptの書き方について教えてください。
- 『root.svg』内『useタグのchildオブジェクト1』の『rectオブジェクト』の色を変えたいと考えていますが、エラーが発生してしまいます。
- どのようにJavaScriptを書けばよいのでしょうか?SVGの記述の方がおかしいのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
大体やりたいことはわかりましたが,様々な点で修正が必要でしょう. 修正点としては概ね次の3つです. (1)svgではスクリプトからuse要素が参照している図形要素に直接アクセスすることはできない. use要素の配下には要素が存在しませんからgetElementByIdメソッドを使ってもnullが返って来るだけです. ※実際には可能なのですが,ブラウザ依存の部分であるため,説明を割愛します. (2)use要素にスタイルを指定することで見た目を変えることが出来る. その為,参照先のスタイルを変更するのではなくuse要素のスタイルを変更することで対処します. (3)但し,use要素でスタイルを変更するには,参照先の図形要素にそのスタイルが未設定である必要がある. 提示のコードのようにuse要素の参照先にfill属性が設定されていると,どうあがいてもfill属性を変更することができなくなってしまいます. 実際に修正したコードを見たほうが判りやすいかと思います. ※なお,手前味噌ですがここいら辺の検証を色々行ったものを公開していますので, そちらを参照していただけるとより理解しやすいかと思います. ・main.htm <!DOCTYPE HTML> <html> <head> <script language="javascript" type="text/javascript"> function OnButtonClick(){ <!-- Root.svg内の楕円の色変更(OK) --> var svgdocMain = document.getElementById("idRoot").getSVGDocument(); var svgMainDaen = svgdocMain.getElementById("idRootObj0"); svgMainDaen.setAttribute("fill", "#00FFFF"); <!-- Child.svgオブジェクト1を非表示(OK) --> var svgSub1 = svgdocMain.getElementById("idRootObj1"); svgSub1.setAttribute("display", "none"); <!-- Child.svgオブジェクト2内の四角の色変更(NG) --> //var svgSub2 = svgdocMain.getElementById("idRootObj2"); //var svgSubRect = svgSub2.getElementById("idChildObj1"); <!--←エラー発生--> //svgSubRect.setAttribute("fill", "#FFFFCC"); var svgSub2 = svgdocMain.getElementById("idRootObj2"); svgSub2.setAttribute("fill", "#FFFFCC"); } </script> </head> <body> <form><input type="button" value="テスト" onclick="OnButtonClick();"/></form> <embed id="idRoot" type="image/svg+xml" src="root.svg" /> </body> </html> ・root.svg <?xml version="1.0" encoding="utf-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="800px" viewBox="0 0 800 800" enable-background="new 0 0 800 800" xml:space="preserve" id="svg_root" > <!-- 1.ROOT楕円 --> <ellipse fill="#00FF00" cx="20" cy="40" rx="15" ry="25" id="idRootObj0"> </ellipse> <!-- 2.Child.svg1 --> <use fill="#00FF00" xlink:href="child.svg#svg_child_g" x="0" y="100" id="idRootObj1" /> <!-- 3.Child.svg2 --> <use fill="#00FF00" xlink:href="child.svg#svg_child_g" x="0" y="200" id="idRootObj2" /> </svg> ・child.svg <?xml version="1.0" encoding="utf-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve" id="svg_child"> <g id="svg_child_g"> <!-- 1.CHILD四角 --> <rect fill="#FF00FF" x="50" y="50" width="40" height="40" id="idChildObj1"> </rect> <!-- 2.CHILD円 --> <circle cx="50" cy="100" r="26.5" id="idChildObj2"> </circle> </g> </svg>
その他の回答 (3)
このようにuse要素で図形のサイズ(width,height属性)まで指定したい場合はsymbol要素を使います. 予めsymbol要素で矩形領域を定め,その中に図形を定義しておきます.use要素がこのsymbol要素を参照している場合,use要素のx,y,width,height属性がsymbol要素の矩形領域にマッピングされ,図形が描画されます. なおsvgのアスペクト比の仕様(preserveAspectRatio),範囲外への描画仕様(overflow)も絡んでくるため,じっくりと取り掛かったほうが良いでしょう. この部分かなりややこしいのですが,使いこなせるようになると一気にsvgの応用範囲が広がるためぜひ頑張ってみてください.
お礼
defghi1977様 再度、ご回答していただきましてありがとうございます。 ・symbol要素 :複数の図形を『1つの図形』として扱える。 という理解をいたしました。 ご提示いただきましたサイトの、5章の「symbol:図形のテンプレート」の箇所が まさに私の質問でした! そういう違いがあるのですね・・・。 まだまだほんの入り口に立ったところですが、精進していきたいと思います! また疑問が発生するとは思いますが、もしお手すきでしたらまたよろしくお願い いたします。 (昨日何度かお礼の書き込みを試みたのですが、なぜかうまくいかず、遅くなり申し訳ございませんでした。) お世話になりました!ありがとうございました。
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2280)
なるほど、<object>や<embed>の内部にアクセスできるようになってたんですね。 No.1は無視してください。失礼しました。
お礼
No1の方でお礼をさせていただいております。 よろしくお願いいたします。
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2280)
<object>や<embed>を使った場合は、その内部にJavaScriptでアクセスする事が出来ないようです。 (ブラウザのバージョンアップにより対応しているかもしれませんが、動かないなら対応していない可能性が高いと思います。 Flashと連携できるのは、FlashPlayerPluginが特殊なだけです。) SVGファイルの中でJavaScriptを使えば、SVGファイルの中だけであれば動きます。 HTMLドキュメントとSVGドキュメントを連携させるのであれば、 <svg>を使ってSVG画像を表示するか、 Ajaxでsvgファイルを読み込んで、<svg>のinnerHTMLに入れるしかないと思います。 GoogleGroups、HTML5-dev https://groups.google.com/forum/#!msg/html5-developers-jp/MnJ4rkwVAxE/isS9YxyBG1UJ メール本文よりサンプルへのリンク http://dl.dropbox.com/u/1236764/temp/svgmap/test.html
お礼
様 ご回答の程、ありがとうございます! ・"SVGファイルの中で" JavaScript ・innerHTML使用 このような方法も取れるのですね。 いろいろ応用が利きそうですね。 まだまだ精進が必要です(汗) また、質問をさせていただきました際には、よろしくお願いいたします。 本当に、ありがとうございました!
補足
お礼の「taloo様」と入力したはずが、名前が消えてしまいました。 申し訳ございません。
お礼
defghi1977様 ご回答の程、ありがとうございました。 ソースの修正方法までご提示いただきまして感激です! あのサイトの作者様だったのですね! 実は今かなり勉強させていただいております。 子SVGの、 ・固定の色の図形を元ファイルで固定 ・可変にしたい色の図形を元ファイルで無指定 とすることで、(3)の仕様により、可変図形にだけ親SVGの指定が効いてきているのですね。なるほど理解いたしました! ↑と同じように考えて、四角に対して、親svgの方で「width/height」を指定してみましたが、まったく表示されませんでした。。。 こちらはまた違うのでしょうか? 【子svg】 <g id="svg_child_g2"> <!-- 3.CHILD四角 --> <rect fill="#FF00FF" x="100" y="100" id="idChildObj3"> </rect> </g> 【親SVGから下記のように呼び出し】 <!-- 3.Child.svg2 --> <use xlink:href="child2.svg#svg_child_g2" x="0" y="0" width="40" height="40" id="idRootObj3" /> またご回答をいただければ幸いです。 よろしくお願いいたします。