SVGのcircleがstrokeによって見切れなくする方法(stroke-widthを増やすと見切れちゃう)

svgの circle でアウトライン付の円を描くと見切れたことはありませんか?

その理由と見切れなくする方法を紹介します。

結論:見切れなくする方法

<svg width="100" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <circle fill="#00f" stroke="#000" stroke-width="10" cx="50" cy="50" r="45"></circle>
</svg>

直径100の円を描きたいとします。その場合、半径 50 から「stroke-width」の半分の値 5(10÷2)を引いた値 45を r(半径)に指定すると、正しく直径100の円が描けます。

stroke-widthを指定する場合のrの値

下記の計算式で r の値を算出しましょう。
r = 円の半径 - (「stroke-width」 ÷ 2)

見切れてしまう理由

見切れる円を実際に見てみましょう。

円が見切れてしまう

<svg width="100" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <circle fill="#00f" stroke="#000" stroke-width="10" cx="50" cy="50" r="50"></circle>
</svg>

r の値に半径 50 を入れると、アウトラインの部分が見切れてしまいます。r は半径なので正しく表示できそうですが、うまくいきません

円の外側にアウトラインを引いているかもしれませんので、半径から「stroke-width=”10″」引いてみましょう。

円が小さくなる

<svg width="100" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <circle fill="#00f" stroke="#000" stroke-width="10" cx="50" cy="50" r="40"></circle>
</svg>

r の値に半径 50 から「stroke-width=”10″」を引いた値 40を入れてみましょう。一見正しく円が描かれているように思えます。ですが、下記画像をご覧ください。

引用:firefoxの要素の検証-svgのサイズ
引用:firefoxの要素の検証-円のサイズ

左(上)の画像の svgの幅は100pxになっています。右(下)の画像を見てください。円の直径が 90になっているのが分かります。

実際に右側に直径100の円と並べてみました。左が明らかに小さいのが分かるかと思います。
ということで、半径から「stroke-width」を引いてもうまくいかないことが分かりました。

アウトラインはどのように描かれている?

見切れた円を改めて見てみましょう。

上下左右のアウトラインがちょうど半分見切れているのが分かります。少し拡大して図を用いて説明します。

直径100の円にアウトラインを10描いた場合

上の図は実際にsvgで黒いアウトライン付の青円を描いたものに、説明用の図を書き足したものです。順番に説明しますので、下記をご覧ください。

  1. 赤線の円直径100(半径50)の円になります
  2. この赤線の円、つまり直径100の円に幅10のアウトライン(stroke-width=10)を描きます
  3. 図にあるとおり、直径100の円にアウトラインを描くと、円の外周のに肉付けするようにアウトラインを描きます
  4. 少し分かりにくいかと思います。緑の線をご覧ください。5の部分が円の外周のと書いた部分で、10がアウトライン全体です。

つまり、下記のように r(半径)=50、stroke-width(アウトラインの幅)=10 と指定した場合、半径50の円の外周の内側と外側に 5ずつ肉付けしてアウトラインを描くため、アウトラインを含めた円の半径は55となり、直径110の円を描くことになってしまいます

<circle fill="#00f" stroke="#000" stroke-width="10" cx="50" cy="50" r="50"></circle>

ここで、最初に結論であげた式をもう一度見てみましょう。

stroke-widthを指定する場合のrの値

下記の計算式で r の値を算出しましょう。
r = 円の半径 - (「stroke-width」 ÷ 2)

なぜ、円の半径から「stroke-width(アウトライン)」 ÷ 2を引いているか分かっていただけたかと思います。そうです、円の外周の外側に肉付けされる幅、つまり「stroke-widthの半分」を半径から引くことで描きたい直径の円を描くことができるのです。上の計算で「r」の値を決めないと描きたい円より大きくなってしまいます。

円が見切れてしまう理由

svgを書くとき、円の大きさは直径100pxという想定で、表示する領域を幅100px、高さ100pxで設定しています。ですが、circleで描かれる円は直径110pxの円です。すると上下左右5pxずつはみ出てしまい、見切れてしまうわけです。

svgについて記事を書いているのですが、下記2つあたりがこの記事に関連が深いかなと思います。理解を深めたい方は是非ご覧ください。

関連記事

SVGについて9ページに渡って、調べたり・自分で検証したりしました。svgの理解に繋がるかもしれません。興味のある方はご覧ください!
※上の2つの記事も含まれています

SVGについての目次