この記事は、SVG Advent Calendar 2016 の3日目の記事です。
SVG Advent Calendar には、このような記事も過去に投稿しています。
- clip と transform との組み合わせ - 職業プログラマの休日出勤
- 手入力のSVGでクリスマスツリーを描こう☆ - 職業プログラマの休日出勤
- マスター・オブ・円弧 #SVG - 職業プログラマの休日出勤
さて。
年末ということで、宝くじ や 占い、それに類するものに興味をお持ちの方も多いかと思います。私自身はそのようなものは好きではないのですが、くじ等を作る側(射幸心を煽る側)の人間として各種法令を遵守しながら立ち回ることは嫌いではありません。ここでは、くじを作る側の人間として、SVGでスクラッチくじを作る手法を紹介したいと思います。
まずは完成品のご紹介
さすがにブログ記事の中でJavaScriptを動作させるのはどうなんや…ということで、別のサイトにHTMLファイルを置くという形でご紹介いたします。
https://www.tmotooka.com/svg_scratch.html
このページにアクセスすると、銀色(実態は灰色ですが)の部分をマウス操作やタッチ操作で削ることができ、削ると隠されていたメッセージが表示されます。
「もう一度 くじ を引く」ボタンを押すと、銀色の覆いは元に戻り、中のメッセージはランダムで切り替わります。
こすったときに何が起きているのか?
まず初めに、SVG画像としては、銀色の覆いの向こう側には、あとで表示されることになるはずのテキストのメッセージが描かれています。その手前のレイヤに、銀色の長方形が描かれています。
JavaScript のコードでは mousedown
mousemove
touchstart
touchmove
などのイベントを捕捉し、マウスカーソルの位置やタッチ位置を把握しています。
その動いた軌跡を、ある程度の太さの線分で結び、その線分で描かれた領域だけ銀色の覆いが非表示にする、ということを mask という機能を使って実現しています。
mask とは
SVGで描かれている内容のうち、指定した領域を透明にすることができます。領域は、<mask>
で囲まれた内側で、通常のSVGと同じように描くことで指定することができます。白く塗り潰された領域は描画され、黒く塗り潰された領域は透明になります。
mask の適用先では mask="url(#{mask要素のid})"
という形で適用するべきマスクを指定します。
詳細な説明は、こちら。
Clipping, Masking and Compositing – SVG 1.1 (Second Edition)
銀色の覆いをカスタマイズしてみる
スクラッチの仕組みは、くじではなくプリペイドカードなどにおいても頻繁に用いられます。そのようなものの中には銀色の覆いに対して模様を描いていることもあります。
今回紹介したスクラッチくじでも、そのような模様を描くことが可能ですし、実は少し修正するだけで模様を登場させることが可能です。
ソースの中に path id="wave"
と書かれた部分があると思います。この要素の stroke="none"
を stroke="#000000"
に変えることで、3本の黒い波線を表示させることが可能です。この path
はmask適用している <g>
タグの内側に居ますので、削る操作をしたとき、銀色の覆いと一緒に削れていきます。
何故これを作ったのか?
今年の8月に、名古屋のWeb界隈の皆様の集まり「WCAN」主催のイベント「WCAN mini 2016 Vol.2 SVG Maniax in NAGOYA」に参加してきました。
wcan.jp
このときの参加レポート: 名古屋のSVGイベントに参加してきました - 職業プログラマの休日出勤
参加レポートには書いていませんが、この懇親会においてどなたかが「SVGでスクラッチくじとか作れたら面白そうだよね」という発言をされていました。このとき私は十分な量のお酒を頂いていたので誰の発言だったのかを思い出すことができないのですが、ここで私は「実装するぞ!」という宣言をしたことだけは覚えています。それから忙しい日々が過ぎる中で「早く SVGスクラッチくじ を作りたい」という想いは募る一方でした。
このときの約束を果たすことができて、私は幸せです。