2014年4月1日火曜日

Snap.svgの使い方をまとめました

Snap.svgの使い方まとめ

svg時代のjavascriptライブラリ「Snap.svg」について,日本語のドキュメントが極めて乏しいことからまとめてみました.豊富なapiを使い方を含めて全て1枚のwebページに収めたために,とっても重い代物になっちまいましたが,中々使えるものになったかと自負しています.

9 件のコメント:

  1. はじめまして。突然のコメント投稿申し訳ありません。
    ドット絵をsvgに変換する(ver2)を最近よく使わせてもらっていて、オフライン版も使ってみようと思ったのですが
    web上と同じようにキチンと変換は出来るのですが、svgファイルの保存が出来ないです。(firefox IEで試しましたがダメでした)
    何か自分の方の設定が悪かったりするのでしょうか? もしご迷惑でなければ、返答お願いします m(_ _;)m

    返信削除
  2. セキュリティ絡みの点からwebブラウザの動作はローカル動作とオンライン動作とで異なる場合があります.当方の環境では上手く動作しているため,環境依存の部分が大きいのかも知れません.
    当初はスクリプトの公開を主眼に入れていましたが,ローカルでの動作をも鑑みるともう少し細工をする必要があるかも知れませんね.検討します.(最悪ソースコードのコピペができるように)

    返信削除
  3. ドット絵svg化スクリプトver2.とりあえずソースコードをコピペ出来るように改良しました.

    返信削除
  4. レスありがとうございます
    自分の環境が悪そうだったので、firefox再インストールやセキュリティソフト、OSの管理者権限確認の設定などを弄って何とか動くようになりました
    お手数をおかけしました
    本当にありがとうございます m(_ _;)m

    返信削除
  5. ああ,連絡有難うございます.こちらでの確認漏れです.まとめの方を改訂します.

    ご指摘のとおりです.Snap.svgでは変数「hub」にElement
    オブジェクトのインスタンスをキャッシュしているのですが,v0.2.0ではこの内容をクリーンアップする仕組みが備わっていませんでした.

    v0.3.0ではこの内容をタイマー処理によって定期的に中身を開放するようになりました.従って原理的にはメモリーリーク問題「は」解決しています.
    ※が,コードを見る限り,ElementオブジェクトをSVG要素から切り離した際に別の不具合を引き起こしそうです.
    (付け焼き刃の修正は却って問題をややこしくする・・・)

    >困難とはつまり、方法はある、という意味でしょうか。
    はい,コードを書き換えることで対処可能です.要は変数hubが外部に公開されていなから発生する問題であるため,この内容を外に出すことで何とかなります.
    詳しいコードはSnap.svgのソースを見ていただくこととして,例えば次のようにします.

    //(1)ローカル変数「hub」を定義した直後に外部に公開するコードを追加
    Snap._.hub = hub;
    ------
    //(2)オブジェクト開放の方法
    //var el = Snap("some selector");というElementオブジェクトがあったとして
    //上記の変数hubからプロパティ[el.snap]をdeleteする
    delete Snap._.hub[el.snap];

    この方法であれば,オブジェクトの開放をスクリプト側で制御することが可能です.

    追記1)
    なお,Snap.svgがメモリーリークするとは言え,原則的に生存期間の短いwebページを想定している場合は意図的にElementオブジェクトを生成・廃棄しない限り問題とはなりません.逆にajax機構を用いて長時間同一のwebページを開きっぱなしにするケースでは容易にこの問題に突き当たるものと考えられます.

    追記2)
    「Snap.svgがメモリーリークする」ケースではそれ以前に多量のSVGElementオブジェクトが生成されていることになります.SVGDOMではこの多量のSVGElementを生成すること自体がアンチパターンであり,最も避けるべきものです.先の対処策はあくまでSVGElementオブジェクトの開放を促すだけであり,多量のSVGElementオブジェクトの開放処理(ガベージコレクション)による不具合を回避するものではありません.

    返信削除
  6. その後ちょっと考えてみましたが,残念ながらv0.3.0でもメモリリーク問題は解決していません.
    SVGのツリー構造を一括してremoveした場合に,配下のElementオブジェクトが開放されません.(おそらく)
    Snap.svgを使う際はご注意下さい.(おそらく今後問題が表面化するものと…)

    返信削除
  7. http://defghi1977-onblog.blogspot.jp/2014/07/snapsvg-v030.html
    にまとめました.

    返信削除
  8. 詳しいご説明とパッチ、ありがとうございます。
    GCまわりの問題では以前にも苦労した経験があり(jQueryでDOM APIを使うと参照カウンタが残る、だとかの問題)、厄介ではありますが、まぁそれを言ったらライブラリうんぬんではなくJavaScriptなどGCな言語についてまわる問題ですし、あらためて、注意が必要と再認識しました。
    それにしても、例のタイマー処理が若干ですが雑に見えたり、他の多数残されているIssueを眺めたりしていると、「まとめ」で指摘されているとおり、やはりSnap.svgは少し今はまだ安定には遠いような気がしてきています。
    こちらのパッチをお借りし、Snap.svgの未来に期待しつつ注意深く利用していこうと思います。
    あらためて、ありがとうございました。

    返信削除
  9. ライブラリを利用する上でその内部構造を理解しておく事は,正しいスクリプトを記述する上で必須となるのですが,Snap.svgではこの点に於いてドキュメントが全く機能していない等,ずさんと言わざるを得ません.
    これは作者の性格に依るところも多いと思われるのですが,提供している機能が機能なだけに余りに勿体無く感じ,例の「使い方」にまとめた次第です.
    幸いにしてオープンソースですし,コードの内容もそれほどトリッキーというわけでもないので,拙作の「使い方」を参考にSnap.svgを読んでみるのも面白いかと思います.
    結構頭を抱えたくなるコードが散りばめられていて楽しいですよ…

    返信削除