<svg width=360px height=150px style="background: #ffa;"> <rect x=50 y=20 width=120 height=40 fill=#f00 /> <ellipse cx=300 cy=80 rx=60 ry=40 fill=#00f /> <text x=30 y=100 fill=#080>これは SVG のサンプルです</text> </svg>です.rect(angle) (矩形),ellipse (楕円)などの単語が見えますから,なんとなく何が書いてあるかは読めると思います.これを HTML ファイルの中の body タグの中に書くことで,上のような図を表示することができます.
自分のホームページを作成するのに,HTML を(原始的に)直に編集している人は
結構いるのではないかと思いますが(私もそうですが),SVG までは
なかなか手がでないという人も多いのではないかと思います(私もそうです).
ということで,このページは,ほぼ,私が SVG になじんでいきながら,
つまり,私もそれほど詳しくないのですが,まあ,読者にとっても,誰か初心者が何か描けるようになる 過程を見るのは役に立つのではないかと思います.
詳しくないとは言いつつ,今,Javascript も勉強していて,そちらの方で,
こういうページに,
いまは,直接手で SVG コードを書くお話をしていましたが,SVG は手で直接書くという使い方のほかに,
まあ,最初に,木の描画機能を使ってみるにしても,使わないにしても,自分で調べながら書けるようになるまで,
このページでは,実際に SVG を書き, それを表示してみながら勉強しようという方針で書いています. そのためには,SVG のコードを書いて,表示する環境を使うことが必要になります.
このページの右上には,
これがそのお試し環境です.下の四角はテキストの入力域になっていて,ここに
このダイアログは
<h2>ようこそ SVG の世界へ</h2> <h3>ようこそ SVG の世界へ</h3> <h4>ようこそ SVG の世界へ</h4>表示は次のようになったはずです.
少しだけ変えて,入力を次のようにしてみましょう.
<h2 align=center style="background: #f99;">ようこそ SVG の世界へ</h2> <h3>ようこそ SVG の世界へ</h3> <h4>ようこそ SVG の世界へ</h4>こんどは,次のようになっていると思います.
このように,このダイアログは
ダイアログの操作について,少し説明を加えておきます.
次にダイアログの上部に
もしかしたら,皆さんの中には,最近のPCで,画面がとても広く,あまりダイアログが文章を覆ってしまうことを心配しなくて良い人もいるかもしれません.そのような人のために,ダイアログを大きく表示するボタン
上のダイアログの画面は,このチュートリアルを書き始めたときの画面です. 場合によっては,ボタンなどが増えている場合もあります.画面ショットは 古いままのものを貼り付けていることもあると思います.画面ショットを 取り直すのは面倒なので,すみませんが,そういう場合はご容赦ください.
ここでは,まず,SVG がどんなものかを感覚的につかむために,いくつかの
SVG で図形を描くためには,まず,
<svg width=400px height=240px> </svg>な風にすればよいのですが,これでは,
<svg width=400px height=240px style="background: #ffa;"> </svg>これを入力域に入れて,「適用」ボタンを押すと
また,400px などは,正式にはダブルクォートでくくって "400px" です.これも省略しても認識して くれるみたいです.もしかしたら,ブラウザによったり,認識できないところも あるかもしれないので,うまく行かなかったらダブルクォートでくくるなどの 対応をお願いします.
この <svg> ... </svg> の間の ... の部分に矩形など,図形の記述を することで,この薄黄色の領域に図形が描画されていきます.
では,まず単純な図形として,
<svg width=400px height=240px style="background: #ffa;"> <rect x=50px y=30px width=100px height=60px /> </svg>ここで,<rect の最後が
<rect x=50px y=30px width=100px height=60px> </rect>と書かなければなりません.しかし,rect の場合開きタグと閉じタグの間に 書くものはありませんので,いちいち,開き,閉じと書くのは面倒です.こういうときは 開きタグ <rect の後ろを /> と書くことによってタグを閉じることができます.
これを入力して,「適用」ボタンを押したら,薄黄色の領域は次のようになったと思います.
<svg width=400px height=240px style="background: #ffa;"> <rect x=50px y=30px width=100px height=60px stroke-width=3px stroke=#00f /> </svg>表示は次のようになったと思います.
No. | RGB(16進数) | 実際の色 | 備考 |
---|---|---|---|
1 | #000 | RGB 全部0 は黒 | |
2 | #F00 | RGB の R で赤 | |
3 | #0F0 | RGB の G で緑 | |
4 | #00F | RGB の B で青 | |
5 | #FF0 | 赤(R) と 緑(G) は黄色 | |
6 | #F0F | 赤(R) と 青(B) は薄紫(ピンクかな?) | |
7 | #0FF | 緑(G) と 青(B) は空色 | |
8 | #FFF | 赤(R) 緑(G) 青(B) 全部の光で白 |
この表をしばらく見ていたら,RGB が 0 か F の色はどんな色か,だいたい想像がつくようになると思います.8つあると大変と思うかもしれませんが,当然,#000 は黒で #FFF は白で,RGB のどれか一つだけが,F のものは,その F になっているところの色な訳ですから,実は,二つが F の3つを覚えれば良いだけなんです.
それで,各 RGB が微妙な値の色がどんな色かは,この基本的な場合に帰着させると,なんとなく分かるようになってきます.例えば,#8FF は, #0FF が空色で,さらに赤(R)を足すので,空色が明るくなって,淡い空色になります.
ところで,以上は,RGB の光を足した体系のお話でしたが,それに対して
絵具を混ぜた場合のように,引いていく体系を
では,矩形の中も,もう少し鮮やかな色で塗ってみましょう.
<svg width=400px height=240px style="background: #ffa;"> <rect x=50px y=30px width=100px height=60px stroke-width=3px stroke=#00f fill=#f00 /> </svg>つぎのように表示されたと思います.
<svg width=400px height=240px style="background: #ffa;"> <rect x=50px y=30px width=100px height=60px stroke-width=3px stroke=#00f fill=none /> </svg>
透明の矩形になりました.
また,色には
<svg width=400px height=200px style="background: #ffa;"> <rect x=80 y=10 width=30 height=160 stroke-width=1 stroke=#000 fill=#0f0 /> <rect x=50px y=30px width=100px height=40px stroke-width=3px stroke=#00f fill=#f00 fill-opacity=0.3 /> <rect x=50px y=90px width=100px height=40px stroke-width=3px stroke=#00f fill=#f00 fill-opacity=0.8 /> </svg>ここでは,fill の不透明度だけ 0.3(上) と 0.8(下) に設定しています.
ここまでに,SVG の領域の作り方と矩形の書き方を見てきました.この章の残りでは 矩形のほかのいくつかの図形を描画してみて,SVG でどんな図形が書けるのかの感触をつかむことにしましょう.それぞれの図形については,この後の章で詳しく学習します.
<svg width=400px height=240px style="background: #ffa;"> <rect x=50px y=30px width=100px height=60px stroke-width=3px stroke=#00f fill=#f00 /> <ellipse cx=100px cy=180px rx=60 ry=30 stroke-width=1px stroke=#000 fill=#0f0 /> <line x1=100px y1=60px x2=100px y2=180px stroke-width=2px stroke=#000 /> <text x=160px y=120>お元気ですか?</text> </svg>これを「適用」すると次のような表示になります.
皆さんの中に,
では,この後,SVG で描画できる図形の詳細について勉強していきましょう.
width や height の単位としては,今まで,px つまり計算機ディスプレイの 画素を単位として指定してきた.その他に次のような単位が使えます.
ビューポートの左上を原点として,x 軸は右へ,y軸は下へのびる座標系です.
ビューポートを定義する属性として,
ここでは,
rx, ry を指定した rect の例を示します.
<svg width=400px height=200 style="background: #ffa;"> <rect x=10 y=10 width=100 height=50 fill=#f00 stroke-width=1 stroke=#000 /> <rect x=10 y=70 width=100 height=50 rx=20 ry=20 fill=#f00 stroke-width=1 stroke=#000 /> <rect x=10 y=130 width=100 height=50 rx=40 ry=40 fill=#f00 stroke-width=1 stroke=#000 /> </svg>少し角がまるくなっています.
<text 属性> 表示すべきテキスト </text>です.属性は次の通りです.
<svg width=400px height=200 style="background: #ffa;"> <text x=100 y= 60 font-size=16px fill=#a00>お元気ですか?</text> <text x=100 y= 90 font-size=16px fill=#a00 stroke=#0a0 stroke-width=2px>お元気ですか?</text> <text x=100 y= 140 font-size=32px fill=#00a>お元気ですか?</text> </svg>表示は次のようになりました.
<svg width=400px height=200 style="background: #ffa;"> <text x=10 y= 140 font-size=120 stroke-width=1 stroke=#00f fill=#f00>元気</text> </svg>線の幅が 1 色が #00f (青),塗る色が $f00 (赤)です.
つまり,ここでの文字というのは,輪郭があって,内部が塗ってあるものという訳です.
フォントに関する属性
text には,
●
<svg width=360px height=200px style="background: #ffa;"> <text x=50 y=30 font-size=24px>This is a normal text.</text> <text x=50 y=60 font-size=24px font-family=serif>This is a serif text.</text> <text x=50 y=90 font-size=24px font-family=sans-serif>This is a sans-serif text.</text> <text x=50 y=120 font-size=24px font-family=cursive>This is a cursive text.</text> <text x=50 y=150 font-size=24px font-family=fantasy>This is a fantasy text.</text> <text x=50 y=180 font-size=24px font-family=monospace>This is a monospace text.</text> </svg>
次は和文フォントです.
<svg width=400px height=160px style="background: #ffa;"> <text x=50 y=30 font-size=24px>これは文章です(normal).</text> <text x=50 y=60 font-size=24px font-family='MS Gothic'>これは文章です('MS Gothic').</text> <text x=50 y=90 font-size=24px font-family='Meiryo'>これは文章です('Meiryo').</text> <text x=50 y=120 font-size=24px font-family='Yu Gothic'>これは文章です('Yu Gothic').</text> </svg>
●
<svg width=400px height=160px style="background: #ffa;"> <text x=50 y=30 font-size=24px font-style=normal>これは文章です(normal).</text> <text x=50 y=60 font-size=24px font-style=italic>これは文章です(italic).</text> <text x=50 y=90 font-size=24px font-style=oblique>これは文章です(oblique).</text> </svg>
●
<svg width=400px height=80px style="background: #ffa;"> <text x=50 y=30 font-size=24px font-weight=normal>これは文章です(normal).</text> <text x=50 y=60 font-size=24px font-weight=bold>これは文章です(bold).</text> </svg>
●
<svg width=400px height=220px style="background: #ffa;"> <text x=50 y=30 font-size=24px text-decoration=normal>これは文章です(normal).</text> <text x=50 y=80 font-size=24px text-decoration=underline>これは文章です(underline).</text> <text x=50 y=130 font-size=24px text-decoration=overline>これは文章です(overline).</text> <text x=50 y=190 font-size=24px text-decoration=line-through>これは文章です(line-through).</text> </svg>
その他,text については,文字間のスペーシング,単語間のスペーシング, 配置,パスに沿ったテキストなど,まだ色々な属性があります.
直線の例をいくつか示します.
<svg width=400px height=200 style="background: #ffa;"> <line x1=10 y1=10 x2=200 y2=40 stroke=#a00 stroke-width=1 /> <line x1=10 y1=40 x2=200 y2=70 stroke=#00a stroke-width=5 /> <line x1=10 y1=70 x2=200 y2=100 stroke=#000 stroke-width=2 stroke-dasharray="2" /> <line x1=10 y1=100 x2=200 y2=130 stroke=#000 stroke-width=2 stroke-dasharray="2 5 2" /> </svg>次の図がこれを表示したものです.
<svg width=400px height=200 style="background: #ffa;"> <polyline points="50, 20 250, 20 150, 120" stroke=#000 stroke-width=1px fill=#fff /> </svg>
つまり,結んでいく頂点を
points = "x1, y1 x2, y2 ... xn, yn"という具合に属性 points の値として書くわけです.ここでは,区切り記号として「,」と空白を使っていますが,実は,どちらでも良いです.コンマや空白記号で区切られた数値の並びは,前から二つずつ x 座標と y座標のペアと解釈されていきます.ただ,全部,同じ記号を使うと,人間が読み取れなくなるので,適当に使い分けているだけです.いっそのこと,カッコも空白記号として扱ってくれれば読みやすい工夫ができるのにとも思いますが,やってみたところダメでした.
それで,これを表示すると次のようになります.
与えられた頂点が指定された stroke の色と stroke-width の太さで結ばれて行っています.内部に相当するところは,fill の色で塗られています.これを none にすると透明になります.
<svg width=400px height=200 style="background: #ffa;"> <polyline points="50, 20 250, 20 150, 120" stroke=#000 stroke-width=1px fill=none /> </svg>
多角形
多角形は,polyline の代わりに,polygon と書きます.最初の点と最後の点が結ばれて閉じた図形になることが,polyline と異なります.
せっかくですので,次の図から座標を拾って,矢印でも描いてみましょう.
座標値は 20倍にしました.
<svg width=400px height=200 style="background: #ffa;"> <polygon points="20, 80 120, 80 120, 40 180,100 120,160 120,120 20, 120" stroke=#000 stroke-width=2px fill=#c95 /> </svg>
パスの属性は次のようなものです.
属性 d 以外はすでに他の要素で出てきていますので,書き方や意味は分かると 思います.したがって,ここでは d の記述方法と意味について説明します.
コマンドというのは,
コマンド名 引数 ...という形の記述の列のことです.コマンド名と引数,引数同士,複数のコマンドの間には空白やコンマを任意個はさむことができます.コマンド名は1文字の英文字です. 大文字のコマンドは絶対座標系のコマンド,小文字のコマンドは相対座標系のコマンドです.コマンド名は1文字ですので,コマンド名と最初の引数の間に空白は無くても構いません.
この記述体系には,カレントポイントという概念があります.現在,自分がいる座標と思えばよいでしょう.パスで使われるコマンドと引数を列挙します.
簡単な例を載せておきます.
次のものが,これの SVG コードです.
<svg width=400 height=150 style="background-color: #ffb;"> <path stroke-width=4 stroke=#a00 fill=none d="M50,30 L100,30 M150,30 L200,30" /> <path stroke-width=4 stroke=#00a fill=none d="M50,60 C100,60 100,90 150,90" /> <path stroke-width=1 stroke=#000 fill=none d="M50,60 L100,60 L100,90 L150,90" /> </svg>真ん中の青い太い線がベジェ曲線です.その曲線に与えた点を折れ線で結んで,細い黒い折れ線で,ベジェ曲線の上に表示しています.与えた点の方に向かいつつ全体として滑らかになるような線であることが分かると思います.
これらの指定を行った折れ線を示します.線が8px とか太くないと違いは 分かりません.ここでは線幅 16px にしています.
<svg width=400px height=100 style="background: #ffa;"> <polyline points="20, 20 80, 20 40, 80" stroke=#000 stroke-width=16px fill=none stroke-linecap=but /> <polyline points="120, 20 180, 20 140, 80" stroke=#000 stroke-width=16px fill=none stroke-linecap=round /> <polyline points="220, 20 280, 20 240, 80" stroke=#000 stroke-width=16px fill=none stroke-linecap=square /> </svg>
これらの指示を行った結果を示します.
<svg width=400px height=100 style="background: #ffa;"> <polyline points="20, 20 80, 20 40, 80" stroke=#000 stroke-width=16px fill=none stroke-linejoin=miter /> <polyline points="120, 20 180, 20 140, 80" stroke=#000 stroke-width=16px fill=none stroke-linejoin=round /> <polyline points="220, 20 280, 20 240, 80" stroke=#000 stroke-width=16px fill=none stroke-linejoin=bevel /> </svg>
<svg width=400px height=200 style="background: #ffa;"> <polyline points="50, 20 250, 20 150, 120" stroke=#000 stroke-width=2px fill=none stroke-dasharray="6,2,2,2" /> </svg>
<g 共通的な属性定義><g> と </g> に挟まれた要素に個別に属性が定義されていないときは,g で定義された属性が使われます.
要素 ...
</g>
例を示します.
<svg width=360px height=180px style="background: #ffa;"> <g stroke-width=4px stroke=#f00 fill=#afa> <rect x=50 y=20 width=200 height=30 /> <ellipse cx=150 cy=75 rx=100 ry=15 /> <rect x=50 y=100 width=200 height=30 stroke-width=2 stroke=#000 /> </g> <rect x=50 y=140 width=200 height=30 /> </svg>
この例では,上の3つの図形が g でまとめられています.デフォルトの属性は, stroke-width=3 stroke=#f00 fill=#afa です.
最初の2つの図形は個別にこれらの属性を定義していませんから,その属性を 引き継いでいます.3つ目の図形は,stroke-width と stroke だけ定義していますので,それらは新たに定義した値が使われて,背景色 fill は g で定義したものを引き継いでいます.そして,4番目は g の外にありますから,g の定義の影響を受けていません.
こちらは要素を組み合わせて部品を作る役割を持っています.書式は
<symbol id=xxx><br> 要素 ...で,ここに列挙された要素の集まりに xxx という名前を付けます. 例を書きます.
</symbol>
<svg width=360px height=180px style="background: #ffa;"> <symbol id=snowman> <ellipse cx=60 cy=30 rx=50 ry=20 stroke-width=2 stroke=#000 fill=#fff /> <ellipse cx=60 cy=80 rx=60 ry=30 stroke-width=2 stroke=#000 fill=#fff /> </symbol> </svg>これは,黒縁で白塗りの2つの楕円が上下につながっている図に snowman という名前を付けたものです.
symbol は名前を付けただけでは描画されません.これを描画しても,
このように何もない SVG の矩形が表示されるだけです.でも,一応,どんな図形を 定義したか見ておきましょう.それには,symbol の囲みを外してみればよいのですね.
こういう図形でした.
とにかく,symbol は定義しただけでは描画されません. これを描画するには use 要素を使います.use は属性 xlink:href=#id で使う図形の集合の id を指定し,それを描画する位置を x と y の属性で指定します.上の snowman を使った例を示します.
<svg width=360px height=180px style="background: #ffa;"> <symbol id=snowman> <ellipse cx=60 cy=30 rx=50 ry=20 stroke-width=2 stroke=#000 fill=#fff /> <ellipse cx=60 cy=80 rx=60 ry=30 stroke-width=2 stroke=#000 fill=#fff /> </symbol> <use xlink:href=#snowman x=10 y=10 /> <use xlink:href=#snowman x=160 y=10 /> </svg>これで,次のように2つの雪だるまが並んでいる図が表示されます.
<image xlink:href=url x=xxx y=yyy width=www height=hhh />例として,このページのトップの画像を表示するimageを見てみます.
<svg width=400px height=200 style="background: #ffa;"> <image xlink:href=pictures/svg-girl07.jpg x=10 y=10 width=100 /> </svg>次にこのコードを表示したものを示します.
この画像は,このページの下の pictures というフォルダーにあります. 幅の指定だけで,画像の縦横比を保って表示してくれていますね. このimage 要素はラスター画像だけでなく,外部の SVG ファイルを参照して 表示することもできます.
<!-- コメントです. -->です.コメントの部分に改行が含まれていても構いません.
ちなみに CSS と Javascript のコメントは次の通りです.
SVG は,テキスト系の機能が弱いような気がします.例えば,長いテキストを 幅を指定して,折り返して表示するようなタグがありません.それをやるためには あらかじめ,その幅に収まる長さに文字列を分割して,y座標を変えながら 表示する必要があります.一方,HTML には,div や textarea など,幅を決めればテキストの長さに応じて行を折り返してくれる要素があります.
この機能を利用するためか,SVG には,HTML で表示されるものを取り込む機能として,
<foreignObject x=nnn1 y=nnn2 width=nnn3 height=nnn4> HTML の要素の記述 </foreignObject>指定された矩形領域に指定した HTML 要素を表示してくれます.
試しに,div を使って,長いテキストを SVG で折り返して表示してみましょう. 例えば,次のような HTML の記述を考えます.
<div style="width:300px;border: 2px solid #000;"> SVG は,テキスト系の機能が弱いような気がします.例えば,長いテキストを 幅を指定して,折り返して表示するようなタグがありません.それをやるためには あらかじめ,その幅に収まる長さに文字列を分割して,y座標を変えながら 表示する必要があります.一方,HTML には,div や textarea など,幅を決めればテキストの長さに応じて行を折り返してくれる要素があります. </div>ブラウザなどによるこの表示は次のようになります.
これを foreignObject で包んでみます.
<svg width=400px height=300 style="background: #ffa;"> <foreignObject x=50 y=10 width=350 height=280> <div style="width:300px;border: 2px solid #000;"> SVG は,テキスト系の機能が弱いような気がします.例えば,長いテキストを 幅を指定して,折り返して表示するようなタグがありません.それをやるためには あらかじめ,その幅に収まる長さに文字列を分割して,y座標を変えながら 表示する必要があります.一方,HTML には,div や textarea など,幅を決めればテキストの長さに応じて行を折り返してくれる要素があります. </div> </foreignObject> </svg>width=400, height=350 の svg の中に,width=35-, height=280 の foreignObject として記述しています.これを表示すると次のようになります.
div の中が,svg の中に表示されているのが分かります.
私はこれが推奨される使い方かどうかは自信がないですが,一応, 折り返しなど,SVG のテキスト表示の弱い部分は HTML や CSS の方でカバーして表現することが できそうです.
SVG では座標系の変換として
transform="..."という形で指定します.それぞれについて書き方と例を示していきます.
変換の対象としての図形は以前 symbol で使った snowman を使います.
snowman はすでに symbol で定義されていますから,use だけで表示できます.
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 /> </svg>
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 transform="translate(100, 50)" /> </svg>
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 transform="scale(0.5, 2.5)" /> </svg>
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 transform="rotate(30, 0, 0)" /> </svg>
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 transform="skewX(0)" /> <line x1=0 y1=0 x2= 0 y2=120 stroke-width=2 stroke=#000 transform="skewX(0)" /> <use xlink:href=#snowman x=10 y=10 transform="skewX(30)" /> <line x1=0 y1=0 x2= 0 y2=120 stroke-width=2 stroke=#000 transform="skewX(30)" /> <use xlink:href=#snowman x=10 y=10 transform="skewX(60)" /> <line x1=0 y1=0 x2= 0 y2=120 stroke-width=2 stroke=#000 transform="skewX(60)" /> </svg>
skewY(theta) は,x軸を時計回りに theta 度傾けた座標変換です.
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 transform="rotate(30, 100, 50) translate(100, 50) scale(0.5, 1.0)" /> </svg>
少し順わかりにくいかもしれませんので,元の図形,scale(0.5, 1.0) した図形, さらに translate(10, 50) した図形,さらに rotate(30, 100, 50) した図形,それと (100, 50) に描いた半径 5 の円を一緒にかいたものを示します.ソースコードの始めに書いてあるものほど,表示が(z軸について)下になっていて隠れた状態になっています.若干,順番が分かりにくいかもしれませんが,必要なら,HTML/SVG 遊び場で,必つずつ表示してみてください.
<svg width=360px height=180px style="background: #ffa;"> <use xlink:href=#snowman x=10 y=10 /> <use xlink:href=#snowman x=10 y=10 transform="scale(0.5, 1.0)" /> <use xlink:href=#snowman x=10 y=10 transform="translate(100, 50) scale(0.5, 1.0)" /> <use xlink:href=#snowman x=10 y=10 transform="rotate(30, 100, 50) translate(100, 50) scale(0.5, 1.0)" /> <circle cx=100 cy=50 r=5 /> </svg>
ここでは,そのような
仕掛けまで述べると量が嵩張りますので,Javascript のプログラムに入って行くのは 大変なので,ここでは,Javascript のデータからこんなものが生成できるという 例を示すだけにしておきます.プログラマなら「まあ,生成できるよね」と いうことで,自分で作成できるでしょうし,プログラミングを知らない人なら Javascript のプログラムを説明しても分からないでしょうから,ここで, 生成プログラムに入る意味が無いと思うのです.
木を表すJavascript のリストデータを入力して,「生成」を押してくださいグラディエント(連続的に色を変化させる),パターン(パターンで埋めつくす), クリッピング(枠の外を消す)があります.
まず,表示結果からです.
左の線形グラディエントは,右下から左上に向かって,緑から赤に変化していて, 右の放射状グラディエントは中心から周辺に向かって,緑から赤に変化しています.
その SVG コードが次のものです.
<svg width=420 height=160 style="background-color: #ffb;" > <linearGradient id=lin-green-red x1=0% y1=100% x2=100% y2=0%> <stop offset=0% stop-color=green /> <stop offset=100% stop-color=red /> </linearGradient> <rect x=20 y=20 width=160 height=120 fill=url(#lin-green-red) /> <radialGradient id=rad-green-red cx=50% cy=50% r=100%> <stop offset=0% stop-color=green /> <stop offset=100% stop-color=red /> </radialGradient> <rect x=200 y=20 width=160 height=120 fill=url(#rad-green-red) /> </svg>ちょっと沢山の記述ですが,SVG の具体的な記述を見てみましょう.
<stop offset=0% stop-color=green /> <stop offset=100% stop-color=red />という記述があります.これは offset が 0% のところで,緑(green)になり, offset が 100% のところで,赤(red)になるという連続的な色の変化を指示しています.
<stop offset=0% stop-color=blue /> <stop offset=40% stop-color=green /> <stop offset=100% stop-color=red />これを線形グラディエントと放射状グラディエントの中に入れて表示してみます.
結構奇麗ですね.まあ,3色になりましたからね.このSVGソースコードも示して 起きます.
<svg width=420 height=160 style="background-color: #ffb;" > <linearGradient id=lin-green-red2 x1=0% y1=100% x2=100% y2=0%> <stop offset=0% stop-color=blue /> <stop offset=40% stop-color=green /> <stop offset=100% stop-color=red /> </linearGradient> <rect x=20 y=20 width=160 height=120 fill=url(#lin-green-red2) /> <radialGradient id=rad-green-red2 cx=50% cy=50% r=100%> <stop offset=0% stop-color=blue /> <stop offset=40% stop-color=green /> <stop offset=100% stop-color=red /> </radialGradient> <rect x=200 y=20 width=160 height=120 fill=url(#rad-green-red2) /> </svg>
本当は,きちんとグラディエントの記述の仕方と意味をしっかり書くのが良いのでしょうが,これは,皆さんがしばらくいろいろいじって遊んでもらい,必要に応じて, マニュアルを見るというのが良いのかなと思います.今,私もそんなに体力・気力が ありませんし.
という訳で,当面は皆さんに遊んでもらうということですが,いくつか備考的なことを書いておきます.
この SVG コードは次の通りです.
<svg width=420 height=160 style="background-color: #ffb;" > <linearGradient id=lin-green-red3 x1=0% x2=100% > <stop offset=0% stop-color=green /> <stop offset=100% stop-color=red /> </linearGradient> <rect x=20 y=20 width=160 height=120 fill=url(#lin-green-red3) /> </svg>
この SVG コードは次の通りです.
<svg width=420 height=160 style="background-color: #ffb;" > <image xlink:href=pictures/svg-girl07.jpg x=20 y=20 width=100 height=120 /> <image xlink:href=pictures/svg-girl07.jpg x=120 y=20 width=100 height=120 /> <linearGradient id=lin-green-red4 x1=0% x2=100% > <stop offset=0% stop-color=green stop-opacity=1.0 /> <stop offset=100% stop-color=red stop-opacity=0.0 /> </linearGradient> <rect x=20 y=20 width=200 height=120 fill=url(#lin-green-red4) /> </svg>
この SVG コードは次の通りです.
<svg width=400 height=100 style="background-color: #ffb;"> <pattern id=pattern1 width=10% height=15%> <circle cx=4 cy=4 r=3 fill=#a00 /> </pattern> <rect x=10 y=10 width=180 height=60 fill=url(#pattern1) stroke-width=1 stroke=#000 /> </svg>つまり, <circle cx=4 cy=4 r=3 fill=#a00 /> を,この パターンで塗られる図形の横 10% ごと,縦 15% ごとに描画しているわけです.
ここでは,敷き詰めるパターンの間隔を敷き詰められる図形のパーセンテージで指定した訳ですが,これだと,隙間は敷き詰められる図形の大きさに依存してしまいます. そうでなくて,ある大きさのものを隙間なく埋めたい場合もあります.その場合は, patternUnits という属性に,userSpaceOnUse という値を設定し,別の属性,width と height を敷き詰める単位の大きさの記述に使います.
矩形の大きさが縦横2倍になっていますが,敷き詰められるパターンの間隔は変わっていません.この SVG コードは次の通りです.
<svg width=400 height=240 style="background-color: #ffb;"> <pattern id=pattern2 patternUnits=userSpaceOnUse width=10 height=10> <circle cx=4 cy=4 r=3 fill=#a00 /> </pattern> <rect x=10 y=10 width=180 height=60 fill=url(#pattern2) stroke-width=1 stroke=#000 /> <rect x=10 y=90 width=360 height=120 fill=url(#pattern2) stroke-width=1 stroke=#000 /> </svg>これまで述べた機能のほかに,パターンは入れ子にすることもできます. これについては,ここでは省略しますので,ご興味がある場合は SVG の マニュアルなどをご参照ください.
SVG では,まず,そのようなクリッピングの形状としてクリッピングパスというものを定義し,それを別の図形のクリッピングに適用するという手順でクリッピングを行います.
例を見てみましょう.
なにもクリッピングしないときは左の画像です.右の画像では,円の内部に クリッピングしています.この SVG コードを次に示します.
<svg width=400 height=200 style="background-color: #ffb;"> <clipPath id=circleclip> <circle cx=250 cy=80 r=50 /> </clipPath> <image xlink:href=pictures/svg-girl07.jpg x=20 y=20 width=100 height=120 /> <image xlink:href=pictures/svg-girl07.jpg x=200 y=20 width=100 height=120 clip-path=url(#circleclip) /> </svg>つまり,画像を表示する image タグの中の属性 clip-path に clipPath 要素で 定義した circleclip を設定している訳です.
グラフィックスに対する演算を適用することにより,ぼやかしたり,影を付けたり, 光の反射具合を指示することができます.
例をみてみましょう.
ちょっと,目がちかちかするかもしれません.すみません.
左側は普通にイメージとテキストを表示しているものです.それに対して, 右側はぼやかすフィルターを適用しています.画像だけでなく, テキストにもぼやかすフィルターが適用されていることに注意してください.
次の SVG コードがこの画像のコードです.
<svg width=400 height=180 style="background-color: #ffb;"> <filter id=blur1> <feGaussianBlur stdDeviation=2 /> </filter> <image xlink:href=pictures/svg-girl07.jpg x=20 y=20 width=100 height=120 /> <image xlink:href=pictures/svg-girl07.jpg x=220 y=20 width=100 height=120 filter=url(#blur1) /> <text x=40 y=165>SVG Girl</text> <text x=240 y=165 filter=url(#blur1)>SVG Girl</text> </svg>まず,blur1 という識別子(id)のフィルターを定義しています. この定義は予め SVG に定義されている feGaussianBlur というフィルターの パラメータを設定することによって行っています.このように SVG に 予め定義されているフィルターを原始フィルターと言います.
次に,画像の表示とテキストの表示のときに,この定義されたフィルターを
filter=url(#blur1)という属性で参照することで,このフィルターを適用しています.
その他の原始フィルターとして,feOffset があります.これは,平行移動するフィルターです.このフィルターを使う時は,フィルター定義の最初に filterUnits=userSpaceOnUse が必要になります.それは,平行移動のフィルターでは,元の図の占める領域の外側に描画がなされるためです.
この SVG コードは次の通りです.
<svg width=400 height=180 style="background-color: #ffb;"> <filter id=move1 filterUnits=userSpaceOnUse> <feOffset dx=20 dy=10 /> </filter> <image xlink:href=pictures/svg-girl07.jpg x=20 y=20 width=100 height=120 /> <image xlink:href=pictures/svg-girl07.jpg x=20 y=20 width=100 height=120 filter=url(#move1) /> </svg>
複数のフィルターを接続することもできます.それには,filter 要素で 接続する要素を複数書きます.それらは,最初に書いてあるほうから適用されていきます.例えば,次のフィルターは,ぼやかしてから移動しています.もとの画像とくみあわせると,面白い効果が得られるでしょう.
この SVG コードは次の通りです.
<svg width=400 height=80 style="background-color: #ffb;"> <filter id=blur_and_move1 filterUnits=userSpaceOnUse> <feGaussianBlur stdDeviation=2 /> <feOffset dx=20 dy=20 /> </filter> <text x=20 y=40 font-size=24px stroke=#f00 filter=url(#blur_and_move1)>Hello World</text> <text x=20 y=40 font-size=24px>Hello World</text> </svg>
ここでは影を付けるために,1つはぼやかして斜め下に平行移動するフィルターを施した出力,もう一つはそのままの出力の2つを手動で重ねました. これら2つを重ねるフィルターがあれば,この影つけは1つのフィルターで できます.
これは filter の次の3つにより実現できます.
<feMerge>
<feMergeNode in=xxx />
<feMergeNode in=yyy />
・・・
</feMerge>
この SVG コードを次に示します.
<svg width=400 height=240 style="background-color: #ffb;"> <filter id=blur_and_move2 filterUnits=userSpaceOnUse> <feGaussianBlur stdDeviation=2 result=blur2 /> <feOffset dx=20 dy=20 in=blur2 result=kage /> <feMerge> <feMergeNode in=kage /> <feMergeNode in=SourceGraphic /> </feMerge> </filter> <text x=20 y=40 font-size=24px stroke=#f00 filter=url(#blur_and_move2)>Hello World</text> <image xlink:href=pictures/svg-girl07.jpg x=120 y=80 width=100 height=120 filter=url(#blur_and_move2) /> </svg>フィルターは,この他にもいろいろなことができます.ただ,それらを こと細かく述べることはこのページの入門的な性格を超えてしまうので, ここはこれで終わることにします. ご興味のある方は,ページ末の W3C のドキュメントや, インターネット上の filter についての資料を探してみてください (いや,実は私がついていけてないだけですけど).
実は,私は,SVG を勉強するのは初めてではありません.自分の PC の
フォルダを探してみると,20216年の春くらいに,個人で使う必要にせまられて,
pad("PAD01") { s("長さ N の配列 primes[] を用意します") loop("i = 1 to N", size(10)) { s("primes[i] = 1") } loop("i = 2 to sqrt(N)") { switch { s("primes[j] == 1") { loop("j を2から i*j < N の間", size(12)) { s("primes[i*j] = 0") } } s("") } } loop("i = 2 to N") { switch { s("primes[i] == 1") { s("print i") } s("") } } }のような記述から,次のような SVG コードを生成するツールを作っていました.
これは,
まあ,ここで PAD のことに深入りする必要はないので,話を SVG に戻すと,
それで,「もう一度,多少はしっかり勉強した」結果ですが,SVG はいろいろな図形が描けるわけですから,図描画のプリミティブな
関数から実装するのに比べると,とても楽になるわけですが,
私は,この章の最初に言ったように,主にフローチャートや
このようなテキストの折り返しや,そうして描画したものの占める領域の取得は
むしろ,
このように
私は,こういうドキュメントの書式やプログラムに詳しいわけではないので
まあ,今回の SVG の再勉強でも,テキスト系の処理の仕方については,私の中では, 8年前と同じ方法に落ち着いてしまいましたが,一方,SVG の他の特徴を,以前よりは きちんと学ぶことができたので,図生成のターゲット言語に SVG を使うにしても, 以前より見栄えの良いものを作ることができると思います.これが今回の学習の 成果だったと思います.
で,このマニュアルは,私のこのページを書くのに,かなり参考にさせていただきました.実際のところ,このページでは,例が直に見えることやすぐ試して 見れることなどの特徴を除くと,このマニュアルの劣化版になっている のではないかと思うくらい参考にさせていただきました.ここに告白しておきます.
(注)ページトップの挿絵は,perchance.org/ai-girl-image-generator で生成しました. 2024.08.09
計算機(主にソフトウェア)の話題 へ
圏論を勉強しよう へ
束論を勉強しよう へ
半群論を勉強しよう へ
ホームページトップ(Top of My Homepage)