2017-03-13 11 views
1

私は、HTML文書に複数のSVG要素がある状況があります。要素はHTMLルール、ボックスモデル、フレックスボックスを使用してレイアウトされていますが、すぐにグリッドがすぐに使用されると言われています。このjsfiddleは一例で、2次経路演算を使用して、共通の端点とわずかに異なる制御点で描画された一対の塗りつぶした放物線を示しています。他の場合は、様々な厚さの単純な水平線または対角線であってもよい。1つのSVG要素のポイントから別のSVG要素をポイントする方法は?

フィビッドの最初のSVGでは、2つのエンドポイントが同じSVGブロックにあり、ディメンション(SVG単位)はよく知られています。放物線を描くのは簡単です。 (制御点もここに示されています)

ただし、次の2つのSVGがこの問題を示しています。エンドポイントは別々のSVGにあり、ここでは少しのテキストで表される未知の量の「もの」で区切られています。放物線(または何か)が2つを接続できるように、javascriptがエンドポイントとコントロールポイントの座標を書き換える必要があることは明らかです。

第3のSVGの座標系に対する第2のSVGのエンドポイントのSVGユニット座標を取得して、左端のエンドポイントに放物線を接続できるようにするにはどうすればよいですか?

SVGユニットとピクセルの座標比は、任意の図面で一貫していますが、複雑さが増すとその比率は時々変化します(十字を再計算して再描画する必要があります) -SVGアイテム)。

ほとんどのエンドポイントはネストされたSVG要素の2つのレイヤーにネストされます。外側のSVGのSVGユニットはCSSピクセルと同じサイズになりますが、内側のSVGはこの異なる単位サイズは時々変化する可能性があります。

IDまたはクラスは、必要に応じてソリューションに追加できます。

/**CSS*/ 
 

 
svg { overflow: visible; }
<!--HTML --> 
 

 
<svg width="12cm" height="6cm" viewBox="0 0 1200 600" 
 
    xmlns="http://www.w3.org/2000/svg" version="1.1"> 
 
    <title>Example quad01 - quadratic Bézier commands in path data</title> 
 
    <desc>Picture showing a "Q" a "T" command, 
 
     along with annotations showing the control points 
 
     and end points</desc> 
 
    <rect x="1" y="1" width="1198" height="598" 
 
     fill="none" stroke="blue" stroke-width="1" /> 
 

 
    <path d="M500,300 Q300,50 100,300 Q300,75 500,300" 
 
     fill="green" stroke="green" stroke-width="1" /> 
 
    <!-- End points --> 
 
    <g fill="black" > 
 
    <circle cx="100" cy="300" r="3"/> 
 
    <circle cx="500" cy="300" r="3"/> 
 
    </g> 
 
    <!-- Control points and lines from end points to control points --> 
 
    <g fill="#888888" > 
 
    <circle cx="300" cy="50" r="3"/> 
 
    <circle cx="300" cy="75" r="3"/> 
 
    </g> 
 
    <path d="M100,300 L300,50 L500,300 
 
      L300,75 L100,300" 
 
     fill="none" stroke="#888888" stroke-width="1" /> 
 
</svg> 
 
<br> 
 

 
<svg width="2cm" height="6cm" viewBox="0 0 200 600" 
 
    xmlns="http://www.w3.org/2000/svg" version="1.1"> 
 
    <title>Example quad01 - quadratic Bézier commands in path data</title> 
 
    <desc>SVG left endpoint</desc> 
 
    <rect x="1" y="1" width="198" height="598" 
 
     fill="none" stroke="blue" stroke-width="1" /> 
 

 
    <!-- End points --> 
 
    <g fill="black" > 
 
    <circle cx="100" cy="300" r="3"/> 
 
    </g> 
 
</svg> 
 
some stuff here 
 
<svg width="2cm" height="6cm" viewBox="0 0 200 600" 
 
    xmlns="http://www.w3.org/2000/svg" version="1.1"> 
 
    <title>Example quad01 - quadratic Bézier commands in path data</title> 
 
    <desc>SVG right endpoint</desc> 
 
    <rect x="1" y="1" width="198" height="598" 
 
     fill="none" stroke="blue" stroke-width="1" /> 
 

 
    <path d="M100,300 Q-100,50 -300,300 Q-100,75 100,300" 
 
     fill="green" stroke="green" stroke-width="1" /> 
 
    <!-- End points --> 
 
    <g fill="black" > 
 
    <circle cx="100" cy="300" r="3"/> 
 
    </g> 
 
</svg>

(一般的に、座標はこの例は単純化され、同一のY位置を持っています。私が必要とするすべての座標を適切なエンドポイントの位置を決定する方法でありますシステム)。

+0

物事のためのforeignObjectを含む単一のルートSVGを持つ。 (しかし、Internet ExplorerはforeignObjectに問題があります。) –

+0

@FrancisHemsher例を作ったのと同じくらい単純だったら、それは素晴らしい考えです。しかし、HTML/CSSにはSVGにはないレイアウト機能がたくさんあるので、それは巨大な仕事であり、レイアウトを生成する既存のコードに大きな変更が加えられ、すべてをルートSVGに埋め込むことになります。 IEについてはあまり気にしませんので、あなたの考えには問題はありません。 – Victoria

答えて

0

これは私には分かりにくいものでしたが、同僚が助けてくれました。私たちは最終的に困惑しました。その解決策はかなり簡単です。

私たちが物事を困惑させたのは、SVGユーザー座標をブラウザのピクセルに変換するために使用できる座標変換マトリックスがあるように思われます。逆に、SVGユーザー座標に戻すことができます。これにより各開始および終了要素に対して得られる:終了要素点(50、60)に、起動要素内の点(100、400)から描画するために、そして

start = document.getElementById('startSVGElement'); 
spt = start.createSVGPoint(); 
sCTM = start.getScreenCTM(); 

end = document.getElementById('endSVGElement'); 
ept = end.createSVGPoint(); 
eCTM = end.getScreenCTM(); 

は、フィル今

spt.x = 100; 
spt.y = 400; 
ept.x = 50; 
ept.y = 60; 

変換マジック:点におけるそのCTMに基づいて、ブラウザ画素空間にSVG空間から終点に変換し、次に起動素子CTM逆を使用してバックSVG空間への変換:

ept_in_start = ept.matrixTransform(eCTM).matrixTransform(sCTM.inverse()) 

sptとept_in_startは、同じ要素(開始要素)と同じ座標系(開始要素のSVG空間)を基準にした座標を持ち、それらの座標を使用して、座標。

もちろん、ページがリフローする場合は、再計算して再描画する必要があります。そして、各エンドポイントの(x、y)座標に適切なCTMを確実に取得する必要があります。ネストされたSVGと変換がある場合は、多くのオーバーレイ座標系があります。