3

インポートされたSVGの個々の要素に問題があり、どういうわけかアドバイスできることを望んでいました。

Illustratorで作成されたSVGがあり、いくつかのレイヤーがグループ要素になっています。サーバーからSVGを取得すると、次のようなものが表示されます。

<svg>
  <g>
  <g>
</svg>

画像を1つにまとめたくないので、グループごとに分割し、それぞれを独自のsvgタグで囲んで、ページに配置します。

<svg>
  <g>
</svg>

<svg>
  <g>
</svg>

これは素晴らしいです、私が望むように動作します。

私の問題は、これらの各アイテムのパスが元のファイルに描画されているところです。それらはすべてIllustratorファイルから(0,0)引き出されているので、配置しようとすると、他の要素がかつて存在していた左側に大量の空白領域があります。

transform = "translate(-50、-50)"などを使用して要素をシフトしようとしましたが、x、yプロパティがないため、どこにシフトするかわかりません。

描かれたパスをオフセットする方法を知っている人はいますか?または、SVGを読み取り、それを個々の要素に分割して操作する方法がある場合はどうでしょうか。

FirebugまたはChromeを使用すると、個々の要素が正しいサイズで表示されますが、Illustratorで描画されたパスの位置のために、多くの空白が配置されます。

試しましたがcontentDocumentdocumentElementどちらもnullとして表示されます。多分私はそれらを間違って使用していますか?

私はActionscriptの開発者であり、現在JavascriptとjQueryを使用しているため、x、y座標系と要素の配置に慣れていますが、これは正常に機能するようには見えません:/

4

1 に答える 1

5

パスのXY部分を本当に取得したい場合は、パスを変換してすべて絶対コマンドを使用する関数を作成しました。これにより、(生の文字列属性ではなく、DOMインターフェイスを使用して)パスコマンドを実行し、pathSegListすべてのX / Y値を引き出して、それらを使用して実行できます。

ただし、パスのバウンディングボックスを計算し、その周りに直接収まるように要素にをviewBox設定する方がはるかに簡単です。<svg>

// In case you want to leave the old SVG document unchanged
var newGroup = oldGroup.cloneNode(true);
var newSVG = document.createElementNS('http://www.w3.org/2000/svg','svg');
newSVG.appendChild(newGroup);

var bbox = newGroup.getBBox();
newSVG.setAttribute(
  'viewBox',
  [bbox.x,bbox.y,bbox.width,bbox.height].join(' ')
);

transform上記の回答は、移動するグループにaがすでに適用されている場合を適切に考慮していません。(バウンディングボックスは、要素の変換されていないスペースに返されます。)これを説明するデモを作成し、変換された要素の正しいバウンディングボックスを計算しました。

デモ: http: //phrogz.net/SVG/explode_svg_components.xhtml

// Find all the root groups in the original SVG file
var rootGroups = document.querySelectorAll('svg > g');
for (var i=rootGroups.length;i--;){
  var newSVG = elementToSVG(rootGroups[i]);
  document.body.appendChild(newSVG);
}

// Create a new SVG wrapping around a copy of the element
// with the viewBox set to encompass the element exactly
function elementToSVG(el){
  var old = el.ownerSVGElement,
      svg = document.createElementNS(old.namespaceURI,'svg'),
      css = old.querySelectorAll('style,defs');

  // Preserve elements likely needed for correct appearance
  [].forEach.call(css,copyToNewSVG);

  copyToNewSVG(el);

  var bb = globalBoundingBox(el);
  svg.setAttribute('viewBox',[bb.x,bb.y,bb.width,bb.height].join(' '));
  return svg;

  function copyToNewSVG(e){
    svg.appendChild(e.cloneNode(true));
  }
}

// Calculate the bounding box of an element in global SVG space
// accounting for transforms applied to the element
function globalBoundingBox(el){
  var bb  = el.getBBox(),
      svg = el.ownerSVGElement,
      m   = el.getTransformToElement(svg);
  var pts = [
    svg.createSVGPoint(), svg.createSVGPoint(),
    svg.createSVGPoint(), svg.createSVGPoint()
  ];
  pts[0].x=bb.x;          pts[0].y=bb.y;
  pts[1].x=bb.x+bb.width; pts[1].y=bb.y;
  pts[2].x=bb.x+bb.width; pts[2].y=bb.y+bb.height;
  pts[3].x=bb.x;          pts[3].y=bb.y+bb.height;

  var xMin=Infinity,xMax=-Infinity,yMin=Infinity,yMax=-Infinity;
  pts.forEach(function(pt){
    pt = pt.matrixTransform(m);
    xMin = Math.min(xMin,pt.x);
    xMax = Math.max(xMax,pt.x);
    yMin = Math.min(yMin,pt.y);
    yMax = Math.max(yMax,pt.y);
  });

  bb = {}; //IE9 disallows mutation of the original bbox
  bb.x = xMin; bb.width  = xMax-xMin;
  bb.y = yMin; bb.height = yMax-yMin;
  return bb;
}
于 2012-05-16T16:09:58.307 に答える