PerfectVector
著者: Irene Kim1 分で読める

SVGの点線輪郭:間隔と丸い線端を調整する

丸い線端でSVGの点線枠を作り、見える隙間を計算します。独自バッジと編集可能なストロークの例で、閉じた輪郭の不均一な継ぎ目を直します。

目次

SVGの点線輪郭を作るには、形状にストロークを設定し、stroke-linecap="round"と、stroke-dasharray="0 20"のような長さゼロの破線と正の隙間を使います。ストローク幅が点の直径を決めます。dash-arrayの2番目の数値は、パスに沿った点の中心間の距離であり、見える端同士の空白ではありません。

この違いは、線端を丸くした後に枠が詰まって見える場合に重要です。閉じたバッジでは、もう1つ問題があります。繰り返しが開始点に戻る際、残りの間隔が短くなることがあります。以下の例では、線端の形、見える間隔、閉じる継ぎ目を分けて、適切な値を調整できるようにします。

これらは装飾用のストローク設定です。新しいオフセット輪郭を作ったり、描画した各点を別々のカット用パスにしたりするものではありません。

butt、roundの線端と点を比較する

stroke-dasharrayは、描画する破線の長さと、描画しない隙間の長さを交互に並べます。2つの数値のリストなら、繰り返しを確認しやすくなります。MDNのdash-arrayリファレンスでは、奇数個のリストが繰り返され、偶数個の並びになる仕組みも説明しています。

この単独のSVGをファイルにコピーして、ブラウザーで開いてください。元の各パスの長さは240単位、ストローク幅は8です。

<svg xmlns="http://www.w3.org/2000/svg" width="420" height="300" viewBox="0 0 420 300">
 <g fill="none" stroke="#147d78" stroke-width="8">
  <path d="M40 55H280" stroke-dasharray="12 20" stroke-linecap="butt" />
  <path d="M40 145H280" stroke-dasharray="12 20" stroke-linecap="round" />
  <path d="M40 235H280" stroke-dasharray="0 20" stroke-linecap="round" />
 </g>
</svg>

1行目はbuttの線端で12 20を使います。完全な破線は12単位を占め、見える空白は20単位です。2行目は同じ数値でroundの線端を使います。各線端が元の破線の端から4単位伸びるため、完全な破線は20単位を占め、見える隙間は12になります。

3行目では破線の長さをゼロにしています。丸い線端により、この直線上では直径8、中心間隔20単位の点になります。見える端同士の隙間は12単位です。W3CのSVGの描画規則は、ゼロ長の破線も含めて破線端の処理を定義しています。MDNの線端リファレンスは、線端の形状を説明しています。

距離の補正や変換がなく、直線上で完全な破線が離れている場合は、次の計算が役立ちます。

  • Buttの線端:見える破線長 = dash、見える隙間 = gap。
  • Roundの線端:見える破線長 = dash + stroke-width、見える隙間 = gap - stroke-width。
  • 丸い点:直径 = stroke-width、中心間隔 = gap、見える隙間 = gap - stroke-width。

最後の計算がゼロか負なら、点は接触または重なります。曲がる部分では、パスに沿った距離と点同士の直線距離が異なります。直線の隙間の計算を輪郭全体に適用せず、角や曲線を確認してください。

ブラウザーでのbuttの破線、roundの破線、丸い点の比較と、閉じる間隔が不均一なバッジと調整済みバッジの比較
独自のSVG例をブラウザーで描画した結果です。3本の直線はストローク幅が8単位で、2つのバッジは周長600単位に対する32単位と30単位の繰り返しを比較しています。

閉じたバッジ全体に繰り返しを合わせる

次の矩形バッジのパスは、それぞれ180 × 120単位です。周長は2 × (180 + 120) = 600です。パスは左上から始まり、時計回りに進みます。

<svg xmlns="http://www.w3.org/2000/svg" width="620" height="230" viewBox="0 0 620 230">
  <g fill="none" stroke="#147d78" stroke-width="8" stroke-linecap="round">
    <path d="M40 40H220V160H40Z" stroke-dasharray="0 32" />
    <path d="M360 40H540V160H360Z" stroke-dasharray="0 30" />
  </g>
</svg>

左側の0 32では、パス上の距離0、32、64と続き、576まで点の中心が置かれます。開始点へ戻るまでの残りは24単位だけです。閉じる間隔は他の32単位より短く、継ぎ目が不均一になります。SVGの表示を大きくしても、差が拡大するだけで解決しません。

右側の0 30は、周長を20の等間隔に分けます。この矩形では両辺の長さも30で割り切れるため、角に点がそろいます。直線の各辺では、8単位の点の間に22単位の見える空白が残ります。これはこのバッジの繰り返しを直すもので、すべての曲線輪郭で見た目の間隔が同じになる保証ではありません。

自分の輪郭では、希望する点の数を選び、パスの周長をその数で割って、最初の繰り返し距離を求めます。その後、特に曲がり、小さな細部、閉じる点を含め、実際の描画結果を確認します。複数の分離したサブパスを持つ形では、SVGの描画仕様が説明するように、サブパスごとに破線パターンが再開するため、別途注意が必要です。

stroke-dashoffsetは、パス上でパターンの開始位置を動かします。目立つ継ぎ目を見えにくい場所へ置くことはできますが、32単位の繰り返しで600を割り切れるようにはできません。均等に閉じたい場合は、繰り返し距離を合わせます。MDNのdash-offsetリファレンスでは、この位相調整を説明しています。

両方の単独SVGを別々に開き、ブラウザーの描画をこの比較と照合しました。例には単位なしの値を使い、pathLengthによる距離補正、変換、外部CSSはありません。手書きしたこれらのパスを示すものであり、PerfectVectorの変換結果やアプリ間互換性のテストではありません。

サイズと描画設定をそろえる

上の例のように、まずSVG自身の座標の数値を使います。パーセントに置き換えても、パスの周長に対する同じ割合になると想定しないでください。dash-arrayリファレンスは、パーセントがパス長ではなくビューポートを基準に算出されることを説明しています。

pathLengthで距離を正規化する場合は、補正した距離系で破線パターンを計算します。この例の未補正の周長と、別のコード例の正規化した破線値を混ぜないでください。SVGのストロークアニメーションガイドでは、線を描く表現にネイティブのパス長補正を使う別の例を紹介しています。

枠だけを見せたい場合はfill="none"を設定します。ストロークが破線でも、塗りは見えたままになることがあります。点が消える場合は、要素に見えるストロークがあり、CSSがプレゼンテーション属性を上書きしていないか確認します。ストロークが消えるときの確認事項では、間隔を変える前に行うこれらの確認を説明しています。

形状の周囲にストロークのための余裕を残してください。8単位のストロークはパスの外側に広がり、丸い線端は開いた端から伸びます。この例は、点がビューポートで切れないよう余白を含んでいます。納品するSVGを実際の表示サイズでテストしてください。拡大プレビューで分かれる小さな点も、アイコンでは見えにくいことがあります。

画像の準備と枠のデザインを分ける

バッジ内のモチーフがPNGやJPGしかない場合は、PerfectVectorの画像をベクターに変換する手順で、編集可能なSVGを準備できます。枠内へ配置する前に、輪郭、小さな開口部、別々の領域を元画像と比較します。装飾の輪郭は別の形状として保持し、ストローク幅と点の間隔を独立して変更できるようにします。

既存のベクターマスターがあれば保持してください。矩形などの単純な枠は、通常エディターで直接描けます。ベクター化は、オフセット枠を自動設計したり、1本の中心線を復元したり、破線の間隔を選んだりはしません。太いマークをトレースして2つの境界ができた場合は、単線SVGのガイドで、1本の描画経路との違いを確認できます。

カット用途では、装飾のストローク描画を、機械が個々の点形のカットとして解釈すると想定しないでください。エディターで意図した形状を準備し、対象アプリのプレビューを確認します。この記事はブラウザーの描画をテストしたもので、カッターの動作は対象外です。ブログの編集ガイドでは、関連するファイル準備の判断を扱っています。

最終的な輪郭を確認する

ファイルを承認する前に、短い開いたパスと閉じた枠を別々に確認します。線端の形、ストローク幅、繰り返しの数値を確認し、開いたパスの最初と最後のマーク、閉じたパスの継ぎ目を調べます。実際に使うサイズで急な曲線を確認してください。

保存したSVGを対象の環境で開き直します。編集可能な装飾描画が必要ならストローク属性を保持します。対象環境に確定した輪郭が必要なら、別の編集工程として変換し、結果を確認します。後で間隔を修正できるよう、編集可能な元データのコピーを残します。

よくある質問

線端を丸くすると破線が近く見えるのはなぜですか? 丸い線端が破線の両端から伸びるためです。直線上でマークが離れている場合、完全な破線同士の見える隙間は、指定した隙間からストローク幅を引いた値です。

短いカプセル形ではなく、丸い点にするにはどうすればよいですか? ゼロ長の破線、正の隙間、丸い線端を使います。例えば、ストローク幅8でstroke-dasharray="0 20"を使うと、直線上に8単位の点が中心間隔20単位で並びます。

閉じた輪郭で1つだけ隙間が異なるのはなぜですか? 繰り返し距離で周長を均等に割り切れない場合があります。パス長に繰り返しを合わせ、閉じる点と角を確認してください。破線のオフセットを動かすと位相は変わりますが、計算上の不一致は直りません。

参考資料

  1. MDN — stroke-dasharray — 破線と隙間の交互のリストと値の扱いを定義しています。
  2. MDN — stroke-linecap — buttとroundの線端形状、ゼロ長での挙動を説明しています。
  3. W3C — SVGの描画 — 破線の描画、線端処理、サブパスでのパターン処理を規定しています。
  4. MDN — stroke-dashoffset — 破線パターンをずらすオフセットを定義しています。

バッジのモチーフがラスター画像から始まる場合は、PerfectVectorでSVGの候補を準備し、輪郭と開口部を確認してから、別の編集可能な形状として点線枠を追加してください。

ブログのその他の記事

編集しやすい
よりきれいなSVGから始めましょう