web-dev-qa-db-ja.com

SVGで1つの円を別の円から引きます

SVGで1つのシェイプを別のシェイプから減算する方法を見つけようとしています。そのため、中央に穴を開けたり、側面に穴を開けたりします。クリッピングパスのようなものですが、交差点を表示する代わりに、交差点の外側のパーツの1つを表示したいと思います。 1つのソリューション Adob​​e Flexの使用に関わっていますが、適切に実装する方法がわかりませんでした。ブールパス操作を使用してこれをInkscapeで行う方法があることを理解していますが、サークル要素をパス要素に変更するのではなく、そのままにしておきたいと思います。

<defs>
    <subtractPath id="hole">
        <circle r="50" cx="100" cy="100" />
    </subtractPath>
</defs>
<circle id="donut" r="100" cx="100" cy="100" subtract-path="url(#hole)" />
30
Iktys

マスクはあなたが望むものです。 <mask>を作成するには、白のままにしたいものを作成します。あなたが見えたくないものは黒になります。中間の色は半透明になります。

したがって、結果のSVGは擬似マークアップに似ており、次のようになります。

<div style="background: #ddf">
  <svg width="200" height="200">
    <defs>
      <mask id="hole">
        <rect width="100%" height="100%" fill="white"/>
        <circle r="50" cx="100" cy="100" fill="black"/>
      </mask>
    </defs>

    <circle id="donut" r="100" cx="100" cy="100" mask="url(#hole)" />

  </svg>
</div>

マスクを白い長方形で埋めてから、穴を置きたい場所に黒い円を入れます。

58
Paul LeBeau

トリックは、 fill-rule を使用して、クリップパスの表示を制御することです。 (正方形)ドーナツの例は

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg xmlns="http://www.w3.org/2000/svg"
 width="300" height="300">
<defs>
</defs>
   <g transform="translate(50, 50)">
      <path d="M 0 0 L 0 200 L 200 200 L 200 0 z
               M 50 50 L 50 150 L 150 150 L 150 50 z" fill-rule="evenodd"/>
   </g>
</svg>

これは、図形のfill-ruleプロパティを使用して内側の正方形を削除します。必要に応じて、ベジェパスを使用して円を作成するように調整できます。

基本的なクリッピングパスを作成したら、そこからクリッピングパスを作成できます。clip-pathの詳細については、 このMDNエントリ を参照してください。

15

2つの回答は、(1)<mask>を使用するか、(2)“ fill-rule = evenodd”属性を使用して形状を減算することを示唆しています[〜#〜] b [〜#〜]形状[〜#〜] a [〜#〜](A∖B).

両方の提案された答えは、「中間の穴」を解決します(B⊆A)質問の一部ですが、maskアプローチのみが、サイド」部分(B⊈A)evenodd fill-ruleを使用すると、2つの形状が等しく扱われるため、最初の形状と交差しない2番目の形状の部分が結果の一部になります。形状から何かを噛むために、「噛む」形状は、噛まれた形状と境界の一部を共有する必要があります。これは実際には達成するのが面倒かもしれません。

例:別の円から円を引くには、2つの円の交差点である「噛む」形状を作成する必要があります。

マスクアプローチははるかに普遍的です。

2
Renardo

| * |マスク:オブジェクトの減算に使用:

| => fill = "white" =>表示するブロック
| => fill = "black" =>削除するブロック

| => fill = "white" =>表示ブロックをマスクタグ内にも配置し、白を塗りつぶします
| => fill = "black" => Removeブロックをマスクタグ内に配置し、黒を塗りつぶします

| :: |マスクを使用して大きな長方形から中央の小さな長方形を削除する例

<rect x="20" y="20" width="60" height="60" mask="url(#rmvRct)"/>
<mask id="rmvRct">
    <rect x="20" y="20" width="60" height="60" fill="white"/>
    <rect x="40" y="40" width="20" height="20" fill="black"/>
</mask>

| :: |マスクを使用して大きな円から中央の小さな円を削除する例:

<circle cx="50" cy="50" r="45" mask="url(#rmvCir)"/>
<mask id="rmvCir">
    <circle cx="50" cy="50" r="45" fill="white"/>
    <circle cx="50" cy="50" r="25" fill="black"/>
</mask>
1
Sujay U N