今回は、Cさん記事の第2弾です。

本題に入る前に・・・


***************************************************
現在、システム課は絶賛プログラマ募集中です。
興味がある方はこちらから!

***************************************************


現在システム課では、とある会社のエンジニアの方(以下、Cさんと記述)と一緒にお仕事をさせてもらっています。

▼ Cさん記事の第1弾はこちらです ▼
第1弾『サイトのキャプチャを自動取得する』というお話はこちら。

それでは以下新しいCさん記事になります、ご覧下さい

↓↓↓↓↓↓↓↓↓↓ここからがCさんの記事です↓↓↓↓↓↓↓↓↓↓

HTML5が普及するとともに、Flashなどを頼らずブラウザだけで色々な表現力が高いコンテンツを作れるようになりました。

またネット上で無料で使えるJavascriptのライブラリもたくさん共有されまして、うまく活用できれば、こんなクオリティ高いものが一瞬で作れてしまう?!という時代になってきました。

今日は一例として、最近作った「当たりくじ」のサンプルコードを紹介させていただければと思います。

——————————————————————————————
<お題>
サイト上で賞品当選を表示する際、ユーザーに楽しみ感を与えるため、隠しシールを剥がして中身を表示するようにしたい!!!
——————————————————————————————

ん~、シールを剥がす効果を実現するため、マウスの動きにより滑らかなアニメーション効果を実現しなければなりません。

jQueryなどまあまあ使えるけど、CSSが超苦手な僕には難しそうです。

でもシールを剥がすのではなく、擦って中身を見るいわばスクラッチ方式であれば簡単に作れる気がします。

確認してOKをもらって、早速スクラッチのサンプルを作り始めます!

HTML5にはCanvasというブラウザー上で絵を書く仕様を策定されました。

基本的な考え方としては、当選券の画像を先に表示して、その上にHTML5のcanvasを隠しシールとして被せて、
後はCanvasの描画メソッドを使って、隠しシールのレイヤーをマウスの動きで消しとってしまうスクラッチの動きを実現しました。

どういうものを作ったかは実際の動画を見たほうがわかりやすいと思います。

(サンプル:スクラッチ)



先にHTMLとして、当選券と隠しシールのCanvasを定義しました。


<div class="container">
<div class="coupon"><img src="img/coupon_pc.jpg" width="480" height="320" /></div>
<div class="scratch">Canvasに対応したブラウザを用意してください。</div>
</div>

次にCanvasのレイヤーを定義しましたが、何も描画されてないため、当選券が丸見えです。

そして次には初期化の処理として、隠しシールの内容をCanvasに描画します。

// 隠しレイヤーのcanvas対象を取得
var canvas_cover = document.getElementById('cover');
var ctx_cover = canvas_cover.getContext('2d');
// 四角形の描画
ctx_cover.fillStyle = "#999";
ctx_cover.fillRect(0,0, canvas_cover.width, canvas_cover.height); // 塗りつぶし

先にcanvasを定義して、その次描画するCanvasRenderingContext2オブジェクトを取得する。

そして取得した描画オブジェクトのメソッドを使って、グレー色で四角を塗りつぶして、最も地味な隠しシールができました!

次にいよいよ本題のスクラッチの動きですが、ソースコードはこんな感じになります。

$('#cover').bind({
// スクラッチ描画開始
'mousedown': function(e) {
e.preventDefault();
isDrawing = true;
},
// スクラッチ
'mousemove': function(e) {
e.preventDefault();
if (!isDrawing) return;
x = getPageX(e) - $(this).offset().left - boderWidth;
y = getPageY(e) - $(this).offset().top - boderWidth;
ctx_cover.beginPath();
ctx_cover.moveTo(x, y);
ctx_cover.clearRect(x,y,40,40); // 切り抜き
},
// スクラッチ終了
'mouseup': function(e) {
isDrawing = false;
}
});

// タッチやマウス操作する時x座標を取得する
function getPageX(e) {
var pageX = 0;
if (e.originalEvent.touches) {
pageX = e.originalEvent.touches[0].pageX;
} else {
pageX = e.pageX;
}
return pageX;
}

// タッチやマウス操作する時y座標を取得する
function getPageY(e) {
var pageY = 0;
if (e.originalEvent.touches) {
pageY = e.originalEvent.touches[0].pageY;
} else {
pageY = e.pageY;
}
return pageY;
}

スクラッチの一連の動作は3つのマウスの動きにより構成されます。
●マウスを押下:スクラッチ開始する!
●マウスを押しながら移動する:擦る
●マウスアップ:スクラッチ動作がストップ

「マウスが押されている状態の制御」がポイントになります。

isDrawingという変数を使って状態を制御します。

また擦る動きはclearRectというメソッドを使って、canvasから指定した位置とサイズで描画された内容を消すことにより実現します。

最後は各マウスイベントから座標を取得してさらにCanvasの相対位置やCanvasの枠線の太さを配慮してCanvasの中の正確なポイント座標を計算できれば、clearRectのメッソドのパラメータとして渡して、拭き取る動きができるようになりました。

簡単でしょ?!と言いたいところですが、これではスマホとIE8では動かないので、引き続きそちらの対応も紹介したいと思います。

まずスマホに関しまして、HTMLやスクリプトの部分は上記とほぼ一緒ですが、マウス操作がなく、画面をタッチすることになるので、キャッチするイベントを変える必要があります。

そこでjquery.mobileを使えば、各種タッチするイベントを簡単にキャッチできるので、早速HTMLの記述にjquery.mobileのインクルードを追加します。

そうすると、上記のソース中に定義したmousedown、mousemove、mouseupのイベントを下記の対応関係で書き換えればOK!
●mousedown→touchstart
●mousemove→touchmove
●mouseup→touchend

早速、動作確認して、やはりマウスではなく直接指で隠しシールを消しとるので、言葉がうまく表現できないですが、癖になるほど気持ちよかった!です。

個人の好みはさておき、最後はIE8の対応を説明します。

IEは9からHTML5をサポートします。

IE8以下の場合、HTML5のCanvas描画機能を正常に使うため、下記ライブラリを使用します。
https://github.com/arv/explorercanvas

使い方は非常に簡単で、excanvas.jsをサーバに置いて、HTMLのheaderに下記の記述を追加すればOKです。

<!--[if lte IE 8]><script type="text/javascript" src="excanvas.js"></script><![endif]-->

IE6からサポートするらしいですが、さすがにIE6の環境がなくてIE8で動作確認して問題なく動きました!

これでスクラッチ方式の実装が完了、PMも動作確認して満足しているように見えます。

だが、最初に起案されたシールを剥がす方式を忘れてなく、これもやりたいな~とやんわり笑いながら言われました。

早速気を抜かずシール抜かす方式の実装方法について調査し始めました。

頭の中にシールを剥がす動きを想像しながら、ネットで動きが近いJavascriptライブラリがないかを調べました。

突然シールを剥がすことは本のページを巡る動作が似ていることを気づきまして、WEBで本をのようにページをめぐれるサンプルを対象として絞って探しまして、奇跡的に下記のサンプルを見つけました。
https://github.com/blasten/turn.js

サンプルはこちらで見れます。
http://www.turnjs.com/#samples/steve-jobs

滑らかなアニメーションを演出して、マウス反応もよく、何より使い方が非常にシンプルで、ソースコードをほぼ書く必要がなく、ライブラリのjavascriptをインクルードして、初期化の定義をすれば終わり。

最高~!

早速できたものの動作を見てみましょう。

(サンプル:シール捲り)


HTMLはこんな感じ


$(window).ready(function() {
$('#seal').turn({display:"single"}).turn("peel", "br");
});


<div id="seal">
	<div style="background-image:url(img/cover.jpg);"></div>
	<div id="coupon" style="background-image:url(img/coupon.jpg);">
</div>




ここで定義した「seal」は一冊の本と考えていいです。

この本は2ページしかなく、1ページ目は隠しシール、2ページ目は商品券の画像。

その「seal」という“本”をturn.jsのメッソドで初期化すればOKです。

初期化の際、渡すパラメーターとして、まずページをめぐる時に、見えるページは1ページのみにする(実際は本ではなくシールなので、巡ったらいらなくなるので)ため、「display:”single”」で定義しまして、さらにデフォールトの状態でマウスオーバするときに角側に小さい曲がりが表示されますが、初期状態では表示されないです。

本の場合はそれでいいですが、今回の目的から考えるとユーザーにとって、これはシールであり、捲れることわかりづらくなるので、初期表示するときに表示するように、「turn」のメソッドに「”peel”」というパラメーターを渡しました。

最後はページを捲る方向を右から左へするように、「”br”」のパラメーターをつけて。完成!

いかがでしょうか?

今回の開発に当たって、jquery.mobileというスマホサイト開発にとって業界標準的なライブラリも使いまして、それほど知られてなく、excanvas.jsという古いブラウザ対応するライブラリと特定なアニメーションの動きを実現するturn.jsも使いました。

こういうような優秀なツールは無償で公開されるおかげで、僕みたいに能力はそれほど高くない開発者もこんな短時間でそこそこ動くものを作れるようになります。

それぞれの作者に心から感謝しています。

そしてこういうような優秀なツールを世の中に送り出すことができないですが、使い方のノウハウを共有できれば、何方の参考になるかなと思って、この記事を書きました。

↑↑↑↑↑↑↑↑↑↑ここまでがCさんの記事です↑↑↑↑↑↑↑↑↑↑

第1弾『サイトのキャプチャを自動取得する』というお話はこちら。

Cさん、今回も記事提供ありがとうございました。

いかがだったでしょうか?

ちょっとした演出ですが少しでもユーザーに喜んでもらえればと、日々、システム課はユーザーの皆様を第一に考えて業務に取り組んでおります!


***************************************************
現在、システム課は絶賛プログラマ募集中です。
興味がある方はこちらから!

***************************************************

この記事を書いた人

ティーン・カネオカ
ティーン・カネオカ
システム開発担当。
無類の円安好き、1円上がったり下がったりで一喜一憂する今日この頃。
厄年の影響を半端なくうけていて、外出するのが怖い・・・