HTML5
SVG

東京五輪2020エンブレムで学ぶSVG超入門

More than 3 years have passed since last update.


はじめに

先日使用が中止になった1東京五輪2020のエンブレムの描き方を通じてSVGを簡単に勉強しましたので、それを他の方々が追体験できるように編集したSVG超入門記事です。2

ステップバイステップで進みますが、この順は実際に私が勉強を進めた(描いた)順と一緒です。


目指すべきゴール

東京五輪2020のエンブレムは下記の様なデザイン(配置・比率)になっており、これを描くことがゴールになります。

各図形の色はペイントのスポイトで取ってきました。

無題_pp.png

図形
色 (カラーコード)

円 (日の丸)
#E60014

長方形
#373737

左上の三角(金)
#B49146

右下の三角(銀)
#B4B4B4


スタート

ハンズオンしながら記事を読まれる方は、以下のHTMLからスタートになります。

テキストエディタ等にコピーしてから進んでください。


logo.html

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title>東京オリンピック2020 エンブレム</title>
</head>
<body>
<svg width="300" height="300">
</svg>
</body>
</html>


SVGの座標

SVGの座標は左上が原点( 0, 0 )です。

右に行くとx座標が増加し、下に行くとy座標が増加します。


SVGの図形の背景色

図形の背景色はfill属性にカラーコードやHTML Color Nameを指定します。

(初期値はfill="none")

図形の輪郭の線の色と太さは、それぞれstrokestroke-widthで指定できますが、今回は使いません。


四角形を描く

SVGで四角形を描くにはrectタグを使用します。

rectタグの属性は以下の通りです。


  • x

    左上の頂点のx座標

  • y

    左上の頂点のy座標

  • width

    四角形の幅

  • height

    四角形の高さ

画面の真ん中に幅が画面1/3の長方形を描きますので、x="100" y="0" width="100" height="300"を指定します

<svg width="300" height="300">

<!-- 四角形 -->
<rect x="100" y="0" width="100" height="300" fill="#373737" />
</svg>


円を描く

円を描くにはcircleタグを使用します。

circleタグの属性は以下の通りです。


  • cx

    円の中心のx座標

  • cy

    円の中心のy座標

  • r

    円の半径

画面右上に直径が画面1/3の長さになる円を描くので、cx="250" cy="50" r="50"を指定します。

<svg width="300" height="300">

<!-- 四角形 -->
<rect x="100" y="0" width="100" height="300" fill="#373737" />
<!-- 円 -->
<circle cx="250" cy="50" r="50" fill="#E60014" />
</svg>


pathで任意の多角形を描く

左上と右下にある三角の描き方がよくわかりませんが、いずれにせよこれを描くにはpathタグを使うことになりそうです。

とりあえず適当に三角形を描いてふいんき3を出しておくことにします。


pathタグ

pathタグはパスデータ属性dにコマンドとパラメータを指定して任意の図形を描画できます。

コマンドの詳細は参考リンクのページの「path:パス図形の描画」を参照してください。

今は直線を引くだけなので、以下のコマンドのみ使用します。



  • M : 初期位置


  • L : 直線


  • V : 垂直線


  • H : 水平線


  • Z : 初期位置まで直線を引いて線を閉じる

コマンドが大文字の場合は絶対座標指定、小文字の場合は現在位置からの相対座標指定になります。

必ず最後にZを使用し、初期位置Mへ直線を引いて、図形の線を閉じなければいけないことに注意してください。4




  • 初期位置( 0, 0 )から、x座標100まで水平線を引き、そこからy座標100まで垂直線を引き、そこから( 0, 100 )へ直線を引き、初期位置まで直線を引いて図形の線を閉じます。

    (100 x 100の正方形ができます)

<svg width="300" height="300">

<path d="M 0 0 H 100 V 100 L 0 100 Z" fill="#000000"/>
</svg>


三角形を描く

左上の三角は( 0, 0 ) ( 0, 100 ) ( 100, 0 )を頂点に持つ三角形を直線で書きます。

右下の三角は( 200, 300 ) ( 300, 200 ) ( 300, 300 )を頂点に持つ三角形を直線で書きます。

コマンドの書き方は色々ありますが、斜めに引く線はあとで曲線に変更したいのでLで直線を引いておきます。

3.png

<svg width="300" height="300">

<!-- 四角形 -->
<rect x="100" y="0" width="100" height="300" fill="#373737" />
<!-- 円 -->
<circle cx="250" cy="50" r="50" fill="#E60014" />
<!-- 左上の三角形 (↓ ↗ ←) -->
<path d="M 0 0 V 100 L 100 0 Z" fill="#B49146"/>
<!-- 右下の三角形 (← ↗ ↓) -->
<path d="M 300 300 H 200 L 300 200 Z" fill="#B4B4B4"/>
</svg>

くぅ~疲れましたw これにて完結です!


2次ベジェ曲線を描く

前の手順で適当に描いた三角形を円弧の形にくり抜かなければいけません。

参考リンクのページの「2次ベジェ曲線」を見ると、割と簡単に1/4の円弧が書けそうなことがわかります。

2次ベジェ曲線はQコマンドで制御点と終点の座標を指定すればいいみたいです。

では「デザインにある円の半径を求めて、半径の長さをx,yとする制御点を指定して描けばいいのでは」と思いましたが、これはうまくいきません。

エンブレムの中心を原点O( 0, 0 )としたxy座標を考え、右下の三角について見てみます。


  • 自分の安直な考えに基づいた理想と現実

    制御点を( $50\sqrt10$, $-50\sqrt10$ )にした場合の2次ベジェ曲線

1.png

「やったか!?」

「まあ、そうなるな。」

2次ベジェ曲線の制御点は、引きたい曲線の始点と終点の接線が交わる点です。

つまり求めるべき制御点は以下の通りです。

2.png

接線①と②の式はそれぞれ以下の通りです。

5:$y=\frac{1}{3}x-150-\frac{50}{3}$

6:$y=3x-500$

これらの交点(連立方程式の解)が求める制御点の座標ですが、制御点は$y=-x$との交点でもあるので(以下略)

制御点の座標は( 125, -125 )になります。

今回のSVGの座標に直すと( 275, 275 )なので、( 300, 200 )に向かって描く場合の2次ベジェ曲線のコマンドはQ 275 275 300 200となります。

左上の図形の制御点は、原点Oを対称点とする点対称なので、SVG座標は( 25, 25 )( 100, 0 )に向かって描く場合のコマンドはQ 25 25 100 0になります。

斜めの直線を引くLコマンドの部分をこの2次ベジェ曲線コマンドに置きかえて完成です。

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<title>東京オリンピック2020 エンブレム</title>
</head>
<body>
<svg width="300" height="300">
<!-- 四角形 -->
<rect x="100" y="0" width="100" height="300" fill="#373737" />
<!-- 円 -->
<circle cx="250" cy="50" r="50" fill="#E60014" />
<!-- 左上の三角 (↓ ↗ ←) -->
<path d="M 0 0 V 100 Q 25 25 100 0 Z" fill="#B49146"/>
<!-- 右下の三角 (← ↗ ↓) -->
<path d="M 300 300 H 200 Q 275 275 300 200 Z" fill="#B4B4B4"/>
</svg>
</body>
</html>

logo.png

本当の本当に終わり


参考リンク






  1. https://tokyo2020.jp/jp/news/index.php?mode=page&id=1450 



  2. 私のSVG歴は1時間ほどです 



  3. なぜか変換できない 



  4. Zを使用せずに初期位置Mの座標まで線を引いても、図形の線が閉じられたことにはなりません 



  5. y = -3xと直角に交わり、( 50, -150 )を通る1次関数 



  6. y = -1/3 xと直角に交わり、( 150, -50 )を通る1次関数