前のセクションで述べたとおり、<path>
要素は SVG の基本的な図形の中でもっとも強力な要素です。これは、(少なくともよく似ている) 他のすべての図形などを作成するために用いることができます。
加えて、パスは比較的少ない数の制御点を用いてなめらかに流れる線を作成することもできます。同様の見栄えを polyline 要素を用いて作成できますが、なめらかな見栄えを作成するには大量の点を用いる必要があり、また大きなサイズではきれいに拡大されないでしょう。よって、SVG を描画する際はパスをよく理解することが重要です。XML エディタやテキストエディタを用いて複雑なパスを作成するのはやはり難しいのですが、パスの動作を理解することにより我慢できるようになります。
前のセクションで述べたとおり、path 要素の図形は 1 種類の属性 d
で定義されます。d
属性は一連のコマンドと、コマンドが使うパラメータを収めています。よってここでは、利用可能なコマンドとコマンドが何を行うかの例を見ていきましょう。
各々のコマンドは、特定の文字でインスタンス化されます。例えば、"Move to" コマンドは文字 M で呼び出されます。パーサーがこのコマンドに当たったとき、パーサーはあなたがある点に移動させたがっていることを知ります。コマンドの後に続く数値は、移動させたい X 座標および Y 座標を表すパラメータです。従って、(10,10) 動かすには "M 10 10" というコマンドを用います。その後、パーサーは次のコマンドの読み取りを始めます。すべてのコマンドは 2 種類存在しており、1 つは大文字で定義されて、ページ上の絶対座標を指定します。もう 1 つは小文字で定義されて、相対座標 (例: 直前の点から上に 10px、左に 7px 移動) を指定します。
d
属性の座標は 常に単位なし で指定するので、ユーザー座標システムになります。後のチュートリアルで、どのようにパスを他のニーズに合わせて変形できるかを学びます。
直線コマンド
<path>
には、直線のコマンドが 5 つあります。名前が示唆するとおり、各コマンドは 2 転換を結ぶ直線を描画します。最初は "Move To" コマンドである M で、これは前に述べています。繰り返しになりますがこのコマンドは、移動先の X 座標と Y 座標という 2 つのパラメータを持ちます。カーソルがすでにページ上のどこかにあった場合は、2 つの位置を結ぶ線は描画されません。"Move To" コマンドは、どこから描画を始めるかを指定するパスの始点に見られます。
M x y
または
m dx dy
ここまでの描画例を見てみましょう。しかし残念ながら、まだ何も描画されません。行ったことは始点をパス上に動かしただけであるので、まだ何も表示されません。ここでは描画の進行に従って描く点を示していきますので、以下の例では点 (10, 10) だけがある状態になります。ただし、パスだけを描画する場合はこれらの点が表示されないことに注してください。
<?xml version="1.0" standalone="no"?> <svg width="200px" height="200px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 10"/> <!-- Points --> <circle cx="10" cy="10" r="2" fill="red"/> </svg>
実際に線を描画するコマンドは 3 種類あります。もっとも一般的なものは、"Line To" コマンドである L
です。L
は X 座標と Y 座標という 2 つのパラメータを持ち、現在の位置から第 2 の点へ線を描画します。
L x y (または l dx dy)
水平または垂直の線を描画するための、L を短縮したコマンドがあります。H
は水平線を描画、V
は垂直線を描画します。どちらのコマンドも一方向にしか移動しないことから、パラメータは 1 つだけ持ちます。
H x (or h dx) V y (or v dy)
ここで、何かを描画し始めるのに十分なコマンドがわかりました。手始めに簡単なものは、おなじみのシンプルな長方形 (<rect>
要素でより簡単に作成できるものと同じです) を描画することです。これは水平線と垂直線だけで構成されるので、3 種類の "Line To" コマンドすべてを用いる例として最適です:
<?xml version="1.0" standalone="no"?> <svg width="100px" height="100px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 10 H 90 V 90 H 10 L 10 10"/> <!-- Points --> <circle cx="10" cy="10" r="2" fill="red"/> <circle cx="90" cy="90" r="2" fill="red"/> <circle cx="90" cy="10" r="2" fill="red"/> <circle cx="10" cy="90" r="2" fill="red"/> </svg>
最後に "Close Path" コマンドである Z
を用いることで、前出のパスを少し短くすることができます。このコマンドは、現在の位置からパスの始点である最初の点へ戻る直線を描画します。常にパスを閉じる必要はありませんが、パスノードの終端によく置かれます。外見上、大文字コマンドと小文字コマンドの違いはありません。
Z (or z)
従って、前出のパスは以下のように短縮できます:
<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
同じ画像を描画するために、これらコマンドの相対形式を用いることもできます。前に述べたとおり相対形式のコマンドは小文字を用いて表記され、厳密な座標でカーソルを移動するのではなく直前の位置から相対的に移動します。例えば、ここで描いた四角形のサイズは 80 x 80 であるので、path 要素は以下のように書くことができます:
<path d="M10 10 h 80 v 80 h -80 Z" fill="transparent" stroke="black"/>
パスは点 (10,10) に移動した後、右へ水平に点 80 個分、下に点 80 個分、左に点 80 個分、そして始点へ戻るように移動します。
<polygon>
要素や <polyline>
要素でも同じことができるのに、これらのコマンドは何に用いるのかという疑問を持つかもしれません。その答えは、それらの要素ではより多彩なことができない点です。直線を描画するだけであれば、他の形式のいずれかを用いる方が文法的によいでしょう。しかし 開発者が path に慣れていると、そうでない場合よりもより多くの SVG 描画に path を用います。私が知る限り、どちらを使うにしても実際のパフォーマンスにおいて利点や欠点はありません。path のコマンドの構文は単に点を指定する形であり他の 2 要素よりやや複雑であるため、スクリプトを通してパスを生成することは別問題かもしれません。
曲線コマンド
なめらかな曲線を作成するために使うコマンドは 3 種類あります。それらのうち 2 つの曲線はベジェ曲線、3 つめは "円弧" または円の一部です。Inkscape、Illustrator または Photoshop のパスツールを使用していたなら、ベジェ曲線の実体験をすでに行っているでしょう。ベジェ曲線の背景の数学的な説明については、Wikipedia (日本語版) などのリファレンスを参照することが必要です。ここで説明するには情報量が多すぎます。ベジェ曲線には無数の異なる種類がありますが、path 要素ではシンプルな 2 種類だけが使用可能です: 三次ベジェ曲線の C と、二次ベジェ曲線の Q です。
ベジェ曲線
まずは、少し複雑なベジェ曲線である三次ベジェ曲線 C から始めましょう。三次ベジェ曲線は、各々の点に対する 2 つの制御点をとります。従って、三次ベジェ曲線を作成したいときは 3 組の座標を指定しなければなりません。
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
ここで最後にある座標 (x,y) は、線の終点にしたい場所です。他の 2 組は制御点です。(x1,y1) は曲線の始点向けの制御点、(x2,y2) は曲線の終点向けの制御点です。あなたが代数学や微積分学に詳しい場合、制御点は各々の点から始まる線の傾斜を本質的に説明するものです。このときベジェ関数は、線の始めで確立した傾斜からもう一方の側の傾斜へ至るなめらかな曲線を作成します。
<?xml version="1.0" standalone="no"?> <svg width="190px" height="160px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/> <path d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="transparent"/> <path d="M130 10 C 120 20, 180 20, 170 10" stroke="black" fill="transparent"/> <path d="M10 60 C 20 80, 40 80, 50 60" stroke="black" fill="transparent"/> <path d="M70 60 C 70 80, 110 80, 110 60" stroke="black" fill="transparent"/> <path d="M130 60 C 120 80, 180 80, 170 60" stroke="black" fill="transparent"/> <path d="M10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/> <path d="M70 110 C 70 140, 110 140, 110 110" stroke="black" fill="transparent"/> <path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="transparent"/> </svg>
上の例では 9 つのベジェ曲線を作成しています。残念ながらすべての制御点を描画するコードは、上記のコードをかなり大きくしてしまうため取り除きました。完全な図を見てみたい場合は、あなた自身で描画してみましょう。曲線が左側へ移動するにつれて、制御点は水平方向に離れていきます。また曲線が右側へ移動するにつれて、制御点は終点から遠く離れていきます。ここで特筆することは、曲線は 1 番目の制御点に向かって出発し、そして 2 番目の制御点の方向に沿って到着するということです。
長いなめらかな図形を描くために、複数のベジェ曲線をつなぐことができます。この場合はたいてい、ある点の片方の制御点はもう一方で使われる制御点の対向になるでしょう (傾斜を一定に保つ場合)。この場合はコマンド S
(または s
) で示される、三次ベジェ曲線の短縮版を用いることができます。
S x2 y2, x y (or s dx2 dy2, dx dy)
S
は前に示したものと同種の曲線を生成しますが、これが別の S
コマンドや C
コマンドの後に続く場合は、1 番目の制御点が前を曲線で用いられた制御点の対向にするものとみなします。S
コマンドが別の S
または C
コマンドの後にない場合は、その曲線の 2 つの制御点は同じ場所であるとみなします。この構文の例を以下に示し、また右図では指定した制御点を赤色、推測された制御点を青色で示します。
<?xml version="1.0" standalone="no"?> <svg width="190px" height="160px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/> </svg>
利用可能な別のベジェ曲線は二次ベジェ曲線 Q です。こちらは三次ベジェ曲線よりシンプルな曲線です。基本的に制御点を 1 つだけ必要とし、それは始点側と終点側両方の曲線の傾斜を定義します。ゆえに、このコマンドは制御点と曲線の終点を示す 2 つのパラメータを持ちます。
Q x1 y1, x y (or q dx1 dy1, dx dy)
<?xml version="1.0" standalone="no"?> <svg width="190px" height="160px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/> </svg>
三次ベジェ曲線の場合と同様に、二次ベジェ曲線のセットをつなぎ合わせるためのショートカットである T があります。
T x y (or t dx dy)
S と同様にショートカットコマンドは前に用いた制御点を参照して、そこから新しい制御点を推測します。これは、最初の制御点を指定した後は終点を指定するだけで、ある程度複雑な図形を作成できることを意味します。このコマンドは前のコマンドが Q または T コマンドである場合のみ動作することに注意してください。これらのコマンドの後にない場合、制御点は前の点と同じであるとみなして直線が描画されるだけになります。
<?xml version="1.0" standalone="no"?> <svg width="190px" height="160px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="transparent"/> </svg>
三次ベジェ曲線はどのような曲線を描きたいかについて自由度が高いにもかかわらず、どちらの曲線もかなり似た結果になります。どちらの曲線を用いるかはたいてい、そのときの状況や曲線の対称度に依存します。
円弧
SVG を用いて作成できる別のタイプの曲線が円弧 A です。円弧の本質は円または楕円の一部分です。与えられた X 軸方向の半径と Y 軸方向の半径について、2 つの点に接する楕円は 2 つあります (それらが円の半径の範囲内にある限り)。2 つの円について 2 点を結ぶパスは 2 つずつあるため、どのような場合でも考えられる円弧は 4 つあります。このため、円弧はかなり多くのパラメータをとります:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
始めに arc 要素は、円弧の X 軸方向の半径と Y 軸方向の半径を示す 2 つのパラメータを持ちます。これらの説明は不要であると思いますが、もし必要である場合はこれらがどのように振る舞うかを ellipse で確認してください。3 番目のパラメータは、円弧の回転度を示します。これは以下の例でうまく説明されています:
<?xml version="1.0" standalone="no"?> <svg width="320px" height="320px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10" stroke="black" fill="green" stroke-width="2" fill-opacity="0.5"/> </svg>
この例ではページを斜めに渡る path 要素を示しています。その中間で、2 つの楕円弧 (X 軸方向の半径 = 30、Y 軸方向の半径 = 50) が切り抜かれています。1 番目の円弧は x-axis-rotation が 0 であるので、円弧が通る楕円 (灰色で示しています) は直立しています。一方 2 番目の円弧では、x-axis-rotation が -45 度になっています。これは円弧を回転させるので、例の図にあるとおり 2 番目の楕円の短半径がパスの方向に沿うよう一直線に並びます。
前に述べた 4 つの異なるパスは、パラメータで次にある 2 つのフラグで指定します。前述のとおり、パスが通過する楕円は 2 つあり、またそれぞれの楕円でパスが 2 つあることから可能性があるパスは 4 つになります。1 番目のパラメータは large-arc-sweep-flag です。これは円弧を 180 度より大きく描くか小さく描くかを指定し、最終的には与えられた円でどちらの方向にたどるかを決定します。2 番目のパラメータは円弧を負の角で移動し始めるか正の角で移動し始めるかを指定し、本質的には 2 つの円のどちらをたどりたいかを選択します。以下の例は指定可能な 4 つの組み合わせを、それぞれ 2 つの円と共に示しています。
<?xml version="1.0" standalone="no"?> <svg width="325px" height="325px" version="1.1" xmlns="https://www.w3.org/2000/svg"> <path d="M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z" fill="green"/> <path d="M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z" fill="red"/> <path d="M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z" fill="purple"/> <path d="M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z" fill="blue"/> </svg>
まだ推測していないかもしれない最後 2 つのパラメータは、円弧の終端の X 座標と Y 座標を指定します。円弧は図画内に円や楕円の一部を作成するのに簡単な方法です。例えば、円グラフには各々の断片に個別の円弧が必要です。
Canvas から SVG に移行する場合、円弧はもっとも移すのが難しいのですが、とても強力でもあります。完全な円や楕円は、実はパスが問題のある描画になってしまうオブジェクトのひとつです。なぜなら円を周回するパスの始点と終点は同じ場所であり、選択肢になり得る円は無限に存在することから実際のパスが定義されません。これはパスの始点と終点をわずかにずらすことで近似でき、その結果円弧が別のパスの部分に接続されます。ただそのようなときは、代わりに円または楕円のノードを使う方がたいてい簡単です。