前回はFile APIを使って、画像ファイルをCanvasで描画してみました。
この時にCanvasのサイズを画像のサイズに合わせていたのですが、Canvasのサイズを固定にしたい時もありますよね。
ということで、300px * 300pxのCanvasに対して、画像の好きなところだけを表示したいと思います。
hammer.jsは、タッチジェスチャーを使えるようにするライブラリです。やっぱスマホでも使えると良いですもんね。
hammer.fakemultitouch.jsを使えば、PCでもタッチジェスチャーがエミュレート出来ますので、こちらを使って開発します。
また、hammer.showtouches.jsを使えば、PC上のタッチ操作を画面に表示することが出来ますので、こちらも使います。
onload時に次のコードを実行すれば良いかと思います。
Hammer.plugins.showTouches(); Hammer.plugins.fakeMultitouch();
さらに、jQueryと組み合わせるために、jquery.hammer.jsも使用します。
hammer.jsでは、次のような感じで使えます。
$('#canvas').hammer() .on('dragstart', dragstart) .on('drag', drag);
dragstartでドラッグ開始するときに呼び出す関数を登録、dragでドラッグ中に呼び出す関数を登録します。今回は利用していませんが、ドラッグ終了時には、dragendイベントが発生しますので、こちらを利用しましょう。
それぞれの関数はイベントオブジェクトを引数でもらいます。ev.gestureにジェスチャー操作の情報がありますので、こちらで座標などを判定しましょう。
最後に、取得した座標でもって、Canvasに再描画すればよいです。
context.clearRect(0, 0, 300, 300);
context.drawImage(image, left, top);
こんな感じですね。
最終的なコードは次の通りです。次回は同様に拡大縮小をピンチイン、ピンチアウトの操作でやってみたいと思います。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>画像表示</title> <style type="text/css"> html, body, #wrapper { background-color: #ccc; } </style> </head> <body> <div id="wrapper"> <input type="file" name="file" id="file"> <div> <canvas id="canvas" width="300" height="300"></canvas> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script src="js/libs/hammer.min.js"></script> <script src="js/libs/jquery.hammer.js"></script> <script src="js/libs/hammer.showtouches.js"></script> <script src="js/libs/hammer.fakemultitouch.js"></script> <script type="text/javascript"> (function() { $(function() { var canvas = $('#canvas')[0], context = canvas.getContext('2d'), image = new Image(), left = 0, top = 0, width = 0, height = 0, dragStartX = 0, dragStartY = 0; Hammer.plugins.showTouches(); Hammer.plugins.fakeMultitouch(); $('#file').change(function(ev) { var files = ev.target.files; $.each(files, function(index, item) { var reader = new FileReader(); reader.onload = function(file) { var dataUrl = file.target.result; image.src = dataUrl; image.onload = function() { left = 0; top = 0; width = image.width; height = image.height; context.drawImage(image, left, top); } } reader.readAsDataURL(item); }); }); $('#canvas').hammer() .on('dragstart', dragstart) .on('drag', drag); function drag(ev) { left += (ev.gesture.center.pageX - dragStartX); top += (ev.gesture.center.pageY - dragStartY); if (top > 0) { top = 0; } else if (top < -1 * height + 300) { top = -1 * height + 300; } if (left > 0) { left = 0; } else if (left < -1 * width + 300) { left = -1 * width + 300; } context.clearRect(0, 0, 300, 300); context.drawImage(image, left, top); dragStartX = ev.gesture.center.pageX; dragStartY = ev.gesture.center.pageY; } function dragstart(ev) { dragStartX = ev.gesture.center.pageX; dragStartY = ev.gesture.center.pageY; } }); })(); </script> </body> </html>