7

HTML要素を正しくオーバーレイするために、画面ピクセルで任意のSVG要素の境界ボックスを取得する最良の方法を見つけようとしています。これまでの私のアプローチは、オブジェクトの境界ボックスと変換行列を使用.getBBox().getCTM()て取得し、この質問に対する受け入れられた回答で説明されているように、境界ボックスのポイントに変換を適用することでした。

// get the element
var el = $(selector)[0],
    pt = $(selector).closest('svg')[0].createSVGPoint();

// get the bounding box and matrix
var bbox = el.getBBox(),
    matrix = el.getScreenCTM();

pt.x = bbox.x;
pt.y = bbox.y;
var nw = pt.matrixTransform(matrix);
pt.x += bbox.width;
pt.y += bbox.height;
var se = pt.matrixTransform(matrix);

// make a div in the screen space around the object
var $div = $('<div class="bbox"/>').css({
        left: nw.x,
        top: nw.y,
        width: se.x - nw.x,
        height: se.y - nw.y
    })
    .appendTo('body');

ここで私のテストを見ることができます: http://jsfiddle.net/nrabinowitz/zr2jX/

ただし、テストが示すように、変換に回転が含まれている場合、このアプローチは失敗するようです。バウンディング ボックスは回転前に計算されるように見えるため、回転したバウンディング ボックスの角を取得することはできません。

変換された要素の非回転境界ボックスを正しく計算するにはどうすればよいですか?

4

2 に答える 2

5

いくつかの調査の後、これが私が見つけた最良のオプションです:

  • getBoundingClientRect()最新のブラウザのSVG要素でうまく機能するようで、非常に高速ですが、結果はプラットフォームごとに多少異なる場合があります(特に、かなりのストローク幅がある場合)。ただし、@ Sergiuの指摘によれば、これは形状の変化を考慮しておらず、実際のパスやオブジェクトではなく、回転したバウンディングボックスの境界を示しているため、非常に不正確になる可能性があります。ここでの批判を参照してください。フィドルの例:http://jsfiddle.net/stevenbenner/6M5zf/

  • 私の主な目標は、境界長方形の位置の角と中点を取得することでした。最終的に、回転した形状の「実際の」境界ボックスよりも、回転した境界ボックスを使用する方が好ましい場合があると判断しました。上記のアプローチを使用してこれを行うことができました。次に、ポイントを循環させて、N、S、E、Wの位置にできるだけ近づけました。ここで私のフィドルの例を見ることができます:http://jsfiddle.net/nrabinowitz/sPtzV/

于 2012-09-05T17:06:49.900 に答える
3

スキューと回転にはプロファイルの変更、または2つの軸での形状の投影がどのように見えるかが関係するため、これは不可能だと思います。

CTMの回転部分を無視する変換行列を計算することはできますが、新しいBBoxが回転した要素を引き続き囲むという保証はありません。たとえば、円がある場合、回転はバウンディングボックスの寸法に影響しません。一方、ベースパスとしてダイアモンドがあり、それを45度回転して、最終的には正方形になる場合、バウンディングボックスは異なります。元々は対角線を測定していましたが、現在は辺の長さを測定するバウンディングボックスを入手する必要があります。CTMをどのように使用しても、形状の変化を考慮に入れることはできません。

したがって、ローテーションは実際には非常に重要であり、それを無視することはオプションではありません。ただし、ローカルバウンディングボックスと変換行列だけでは、回転したときに形状プロファイルがどのように変化するかについては何もわかりません。

于 2012-08-30T22:02:47.737 に答える