🎯 やりたかったことは?
SVGの path を扱っていると、
「MとLは分かるけど、Cって何だっけ?」
「Aの引数が毎回分からなくなる」
「大文字と小文字って何が違ったっけ?」
みたいなことが結構あります。
自分も実務でSVGの path を扱うことがありますが、
直線系は覚えていても、ベジェ曲線や円弧あたりは毎回すぐには出てきません。
そこで、d 属性でよく使うコマンドを
すぐ確認できるようにまとめておきます。
🚀 急いでいる人向け
path の d 属性では、
文字ごとに「次にどんな線を描くか」を指定します。
| コマンド | 用途 | 基本形 |
|---|---|---|
M |
開始位置へ移動 | M x y |
L |
直線 | L x y |
H |
水平線 | H x |
V |
垂直線 | V y |
C |
3次ベジェ曲線 | C x1 y1 x2 y2 x y |
Q |
2次ベジェ曲線 | Q x1 y1 x y |
A |
円弧 | A rx ry rotation large-arc sweep x y |
Z |
パスを閉じる | Z |
例えば三角形なら、
<path
d="M50 20 L150 120 L20 120 Z"
fill="#4CAF50"
stroke="#333"
stroke-width="3" />
です。
M50 20
→ 開始位置
L150 120
→ 直線
L20 120
→ 直線
Z
→ 開始位置まで閉じる
大文字は絶対座標、小文字は相対座標です。
M 100 100
→ SVG全体の (100, 100)
m 100 100
→ 現在位置から (100, 100) 移動
💡 この記事で分かること
- SVG
pathのd属性の基本 -
M/L/H/Vの使い方 -
C/Qでベジェ曲線を描く方法 -
Aで円弧を描く方法 -
Zで図形を閉じる方法 - 大文字と小文字の違い
- 複数のコマンドを組み合わせる方法
path の d 属性とは?
SVGの path は、
d 属性へ座標とコマンドを並べて形を作ります。
<path
d="M20 20 L120 20 L120 120 Z"
fill="none"
stroke="#333" />
d の中身を分けると、
M20 20
L120 20
L120 120
Z
です。
SVGはこの命令を左から順番に処理していきます。
M:開始位置を指定する
M は Move To です。
線を描かずに、現在位置を指定した座標へ移動します。
<path
d="M50 50"
stroke="black" />
基本形は、
M x y
です。
例えば、
M50 100
なら、
x = 50
y = 100
へ移動します。
M 自体では線は描かれません。
そのあとに L や C などを続けて線を描きます。
<path
d="M20 50 L200 50"
fill="none"
stroke="black" />
L:直線を引く
L は Line To です。
現在位置から指定座標まで直線を引きます。
<path
d="M20 20 L150 100"
fill="none"
stroke="black" />
基本形は、
L x y
です。
例えば、
M20 20
L150 100
なら、
(20, 20)
↓
(150, 100)
まで直線を引きます。
複数続けることもできます。
<path
d="
M20 20
L150 20
L150 120
L20 120
"
fill="none"
stroke="black" />
H:水平方向へ線を引く
H は Horizontal Line To です。
Y座標を変えず、
X座標だけを変更して水平線を引きます。
<path
d="M20 50 H200"
fill="none"
stroke="black" />
基本形は、
H x
です。
例えば、
M20 50
H200
なら、
(20, 50)
↓
(200, 50)
になります。
L で書くなら、
L200 50
と同じ結果です。
V:垂直方向へ線を引く
V は Vertical Line To です。
X座標を変えず、
Y座標だけを変更して垂直線を引きます。
<path
d="M50 20 V150"
fill="none"
stroke="black" />
基本形は、
V y
です。
例えば、
M50 20
V150
なら、
(50, 20)
↓
(50, 150)
になります。
C:3次ベジェ曲線を描く
C は Cubic Bézier Curve です。
3次ベジェ曲線では、
- 制御点1
- 制御点2
- 終点
を指定します。
基本形は、
C x1 y1 x2 y2 x y
です。
<path
d="
M20 100
C60 20 160 20 200 100
"
fill="none"
stroke="#333"
stroke-width="3" />
それぞれ、
M20 100
→ 開始位置
C60 20
→ 制御点1
160 20
→ 制御点2
200 100
→ 終点
です。
イメージとしては、
開始点
↓
制御点1
↓
制御点2
↓
終点
の4点で曲線の形を決めます。
C は自由度が高いため、
複雑な曲線を作るときによく使います。
Q:2次ベジェ曲線を描く
Q は Quadratic Bézier Curve です。
3次ベジェ曲線の C と違い、
制御点は1つだけです。
基本形は、
Q x1 y1 x y
です。
<path
d="
M20 100
Q110 10 200 100
"
fill="none"
stroke="#333"
stroke-width="3" />
それぞれ、
M20 100
→ 開始位置
Q110 10
→ 制御点
200 100
→ 終点
です。
比較すると、
C
→ 制御点2つ
Q
→ 制御点1つ
になります。
単純な曲線なら Q の方が記述しやすいです。
補足:S と T
タイトルには入れていませんが、
C と Q を使うなら S と T も知っておくと便利です。
S
S は、直前の3次ベジェ曲線を滑らかにつなぐためのコマンドです。
S x2 y2 x y
C にある最初の制御点を省略できます。
<path
d="
M20 100
C60 20 100 20 140 100
S220 180 260 100
"
fill="none"
stroke="#333" />
T
T は Q の滑らかな接続版です。
T x y
<path
d="
M20 100
Q80 20 140 100
T260 100
"
fill="none"
stroke="#333" />
整理すると、
C → S
Q → T
という組み合わせです。
A:円弧を描く
個人的に一番忘れやすいのが A です。
A は Arc で、
楕円の一部を使って曲線を描きます。
基本形は、
A rx ry rotation large-arc-flag sweep-flag x y
です。
例です。
<path
d="
M50 100
A50 50 0 0 1 150 100
"
fill="none"
stroke="#333"
stroke-width="3" />
それぞれの値は、
| 値 | 意味 |
|---|---|
rx |
楕円のX方向の半径 |
ry |
楕円のY方向の半径 |
rotation |
楕円のX軸の回転角度 |
large-arc-flag |
大きい円弧を使うか |
sweep-flag |
円弧を描く方向 |
x |
終点X |
y |
終点Y |
です。
large-arc-flag
値は 0 または 1 です。
0
→ 小さい方の円弧
1
→ 大きい方の円弧
例えば、
A50 50 0 0 1 150 100
と、
A50 50 0 1 1 150 100
では、使われる円弧の大きさが変わります。
sweep-flag
こちらも 0 または 1 です。
0
→ 一方向
1
→ 反対方向
large-arc-flag と sweep-flag の組み合わせによって、
同じ開始点と終了点でも円弧の形が変わります。
0 0
0 1
1 0
1 1
の4パターンがあります。
A は引数が多いので、
自分も毎回ここを確認することが多いです。
Z:パスを閉じる
Z は Close Path です。
現在位置から、
そのサブパスの開始位置まで線を引いて閉じます。
<path
d="
M50 20
L150 120
L20 120
Z
"
fill="#4CAF50"
stroke="#333"
stroke-width="3" />
これで三角形になります。
Z を付けない場合は、
M50 20
L150 120
L20 120
で止まるため、
最後の点から最初の点までは閉じません。
fill を使って閉じた図形を作る場合は、
Z を使うことが多いです。
大文字と小文字の違い
SVG pathでは、
ほとんどのコマンドに大文字と小文字があります。
M / m
L / l
C / c
Q / q
A / a
違いは座標の基準です。
大文字
大文字は絶対座標です。
M100 100
L200 150
SVG全体の座標系で、
(100, 100)
↓
(200, 150)
へ移動します。
小文字
小文字は現在位置からの相対座標です。
M100 100
l100 50
現在位置 (100, 100) から、
x + 100
y + 50
なので、最終的には、
(200, 150)
になります。
自分の場合、
座標を追いかけるときは大文字の方が読みやすいことが多いです。
一方で、
同じ形を現在位置から繰り返すような場合は相対指定が便利です。
コマンドはスペースや改行で分けられる
例えば、
<path
d="M20 20 L120 20 L120 120 Z" />
でも、
<path
d="
M20 20
L120 20
L120 120
Z
" />
でも同じです。
複雑な path を確認するときは、
改行しておくとかなり読みやすくなります。
数値の区切りにカンマも使える
例えば、
M20 20
は、
M20,20
とも書けます。
L100 50
も、
L100,50
で書けます。
実際のSVGを見ると、
スペース区切りとカンマ区切りが混ざっていることもあります。
M のあとに座標を続けた場合
こんな書き方を見ることもあります。
<path
d="
M20 20
120 20
120 120
"
fill="none"
stroke="#333" />
最初の座標は M として扱われますが、
その後に続く座標は直線として扱われます。
つまり、
M20 20
L120 20
L120 120
と同じような意味になります。
短く書けますが、
自分で読む場合は L を明示した方が分かりやすいこともあります。
複数のコマンドを組み合わせる
例えば、
<path
d="
M20 100
H80
C100 100 100 40 130 40
C160 40 160 100 180 100
H240
"
fill="none"
stroke="#333"
stroke-width="4"
stroke-linecap="round" />
この1つの path の中で、
M
H
C
C
H
を組み合わせています。
path は1つのコマンドだけで作るものではなく、
必要な形に合わせて複数をつないで使います。
⚠️ ハマりやすいポイント
M は線を描かない
M20 20
M100 100
としても、
2点の間に線は描かれません。
線を引く場合は、
M20 20
L100 100
のようにします。
大文字と小文字を混ぜると座標を追いにくい
例えば、
M100 100
l50 0
L200 200
では、
M
→ 絶対座標
l
→ 相対座標
L
→ 絶対座標
と途中で基準が変わります。
もちろん正しい書き方ですが、
座標がおかしいときは大文字・小文字の混在を確認します。
A の0と1を逆にすると形が大きく変わる
large-arc-flag
sweep-flag
はどちらも 0 / 1 なので、
値を入れ替えるだけで別の円弧になります。
円弧が想定と逆になった場合は、
まずこの2つを確認します。
Z で閉じる線もstrokeの対象になる
<path
d="M20 20 L120 20 L120 120 Z"
fill="none"
stroke="red" />
Z によって最後の点から開始点へ戻る線も描画されます。
単純に「処理を終了するコマンド」ではなく、
パスを閉じるコマンドです。
📝 まとめ
path の d 属性でよく使うコマンドは次のとおりです。
| コマンド | 用途 |
|---|---|
M |
開始位置を指定 |
L |
直線 |
H |
水平線 |
V |
垂直線 |
C |
3次ベジェ曲線 |
S |
3次ベジェ曲線を滑らかにつなぐ |
Q |
2次ベジェ曲線 |
T |
2次ベジェ曲線を滑らかにつなぐ |
A |
円弧 |
Z |
パスを閉じる |
直線系の、
M
L
H
V
Z
は比較的覚えやすいですが、
C
Q
A
あたりは久しぶりに使うと引数を忘れがちです。
特に A は毎回調べることが多いので、
自分でもこの記事を見返すことになりそうです。