nw.jsでデスクトップアプリを作る(16) - SVG pathをgeometryに変換する(6)

公開:2015-02-28 20:52
更新:2020-02-15 04:37
カテゴリ:nw.js,svg,javascript,nw.jsでデスクトップアプリを作る

昨日のSVGアニメーションだが、FirefoxとIEでは動作しなかった。原因はSVGのお作法にしたがってなかったから。読み取りのみのプロパティに値をセットしようとしていたから。なぜかChromeは代入できたんだよねぇ。

var xml = Q.nfbind(d3.xml);
xml('./horse00.svg','image/svg+xml')
.then(function(svg){
  try {
    document.querySelector('#svg').appendChild(svg.firstChild);

    var gs = d3.select('svg').selectAll('g')[0];
    gs.forEach(function(g){
      var boundingBox = g.querySelector('rect');
      var path = g.querySelector('path');
      convertToRelative(path);
      // ***** 2/28修正 **** //
      var m = path.createSVGPathSegMovetoRel
        (path.pathSegList[0].x - boundingBox.x.baseVal.value - boundingBox.width.baseVal.value / 2.0,
        path.pathSegList[0].y - boundingBox.y.baseVal.value - boundingBox.height.baseVal.value / 2.0
        );
      path.pathSegList.replaceItem(m,0);
      // *** 直接代入できない **//
//        path.animatedPathSegList[0].x = path.animatedPathSegList[0].x - boundingBox.x.baseVal.value - boundingBox.width.baseVal.value / 2.0;
//        path.animatedPathSegList[0].y = path.animatedPathSegList[0].y - boundingBox.y.baseVal.value - boundingBox.height.baseVal.value / 2.0;

      path.setAttribute('d',path.getAttribute('d'));
      g.removeChild(boundingBox);
      g.setAttribute('transform','translate(' + window.innerWidth / 2 + ',' + window.innerHeight /2 + ')');
      window.addEventListener('resize',function(){
        g.setAttribute('transform','translate(' + window.innerWidth / 2 + ',' + window.innerHeight /2 + ')');
      });
      g.style.display = 'none';
    });
  } catch (e) {
    console.log(e);
  }

規格を読むとpathSegListは読み取り専用なのでChromeの動きがおかしいことになるのかな。

interface SVGAnimatedPathData {
  readonly attribute SVGPathSegList pathSegList;
  readonly attribute SVGPathSegList normalizedPathSegList;
  readonly attribute SVGPathSegList animatedPathSegList;
  readonly attribute SVGPathSegList animatedNormalizedPathSegList;
};
    

実際には「m」に相当するSVGPathSegMovetoRelを作るためのファクトリメソッドcreateSVGPathSegMovetoRel()があるので、それで作ったものに変更した値をセットし、pathSegListreplaceItem()でおきかえなければいけないようだ。

これでOKかなと思ったのだがIE11では駄目であった。まあこのアプリはnw.js用なのでクロスブラウザにする必要は全くないのだが、ちょっと気になったので。