S.F. Page

Programming,Music,etc...

ChromeのSVGPathSegListが削除されていた。

気が付くと、下記のサンプルがChromeで動かなくなっていた。ちなみにFirefoxやEdgeでは問題なく動作したのだが。

three.jsのPathのシリアライズ(2) - bl.ocks.org

paths.each(function(){
  // 馬セルの取り出しと座標補正
  var path = d3.select(this);
  console.log(path.node().pathSegList.getItem(0).x);
  convertToRelative(path.node());
  var m = path.node().createSVGPathSegMovetoRel
          (path.node().pathSegList.getItem(0).x - boundingBox.x.baseVal.value - boundingBox.width.baseVal.value / 2.0,
          path.node().pathSegList.getItem(0).y - boundingBox.y.baseVal.value - boundingBox.height.baseVal.value / 2.0
          );

エラーは上記コードあたりで発生。pathSegListundefinedとなってしまっていた。ああ、これは何か規格が変わったのかなと思ってググるとSVGPathSegListが規格から削除されたのでそれに合わせてChrome48バージョンより削除されたらしい。 これに相当する新しいインターフェースはSVGPathDataインターフェースだそうである。

ただ、今使っているChrome49でもこの新しいインターフェースはサポートされていない。

path.node().getPathData()
VM1585:1 Uncaught TypeError: path.node(...).getPathData is not a function(…)

そのために新バージョンおよび旧バージョン用のPolyfillがあるそうだ。

stackoverflow.com

新バージョン

github.com

旧バージョン

github.com

SVGPathSegListを削除するにあたってはそれなりの議論があったようだ。

Issue 539385 - chromium - Remove the SVG pathSegList interface - Monorail

SVGPathSegListインターフェースというのはpathの中身をコマンド・リストのような形で保持し、操作できるインターフェースである。 pathのデータはm 223.44064,240.57693ような文字列をdアトリビュートに設定するのであるが、d中のコマンド文字列を解析し、コマンドをオブジェクトのリストとして保持し、スクリプトから操作しやすいインターフェースとして提供するためにSVGPathSegListが用意されたのである。リストであるから、新たなコマンドを生成して挿入したり、削除したりすることも可能である。

SVGPathSegListが便利なのは、pathの解析が簡単にできることである。もしコマンド文字列からだとパーサーから自前で実装する必要がある。

ChromeでこのSVGPathSegListが削除されたのは、

  • 仕様から削除されたこと
  • もともと使いづらい仕様で、実際ほとんど使われていない
  • 実装に不具合があった

という理由らしい。しかしいきなりばっさり削除するのはどうかな。代替インターフェースであるSVGPathDataインターフェースが実装された後にすればよいのにと思うが。