以下の手順にしたがって進めてください。
- Monacaで新規プロジェクトを作成する
- テンプレートとして Onsen UI V1 Minimum を選択する
- 「設定」→「JS/CSSコンポーネントの追加と削除」でjQuery (Monaca Version)をインストールする
- index.htmlを以下のように修正する。
list.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<script>
ons.bootstrap();
var images = null;
// ギャラリーから画像のパスを取得する
var getPictureFromGallery = function(onSuccess) {
var options = {
quality: 50,
sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
destinationType: Camera.DestinationType.FILE_URI
};
navigator.camera.getPicture(function(imageURI) {
onSuccess(imageURI);
}, onFail, options);
};
// 写真を撮影して保存する
var getPictureFromCamera = function(onSuccess) {
// デバイスのカメラアプリを利用して撮影し保存
var options = {
sourceType : Camera.PictureSourceType.CAMERA,
saveToPhotoAlbum: true,
correctOrientation:true,
destinationType: Camera.DestinationType.FILE_URI
};
// カメラアプリを起動し、撮影して保存
navigator.camera.getPicture(function(imageURI) {
onSuccess(imageURI);
}, onFail, options);
};
function onFail() {
console.log("写真を取得できませんでした");
}
$(document).on('pageinit', '#main-page', function() {
var onSuccess = function(pictureUrl) {
images = [];
var $img = $('<img>');
$img.attr('src', pictureUrl);
images.push({
element: $img,
label: '無加工'
});
myNavi.pushPage('image.html');
}
$(this).on('click', '.take-from-camera', function() {
getPictureFromCamera(onSuccess);
});
$(this).on('click', '.take-from-gallery', function() {
getPictureFromGallery(onSuccess);
});
});
$(document).on('pageinit', '#image-page', function() {
var elements = images.map(function(image) {
var element = $('<ons-carousel-item><div class="converted-image-label-wrapper"><div class="converted-image-label"></div></div></ons-carousel-item>');
$(image.element).addClass('converted-image');
element.prepend(image.element);
element.find('.converted-image-label').text(image.label);
return element[0];
});
elements.forEach(function(element) {
$('ons-carousel').append(element);
});
setTimeout(function() {
imageCarousel.refresh();
}, 100);
});
</script>
</head>
<body>
<ons-navigator var="myNavi">
<ons-page id="main-page">
<ons-toolbar>
<div class="center">画像変換アプリ</div>
</ons-toolbar>
<br>
<ons-list>
<ons-list-item modifier="chevron" class="take-from-gallery">
<ons-icon icon="ion-images"></ons-icon> ギャラリーから選ぶ
</ons-list-item>
<ons-list-item modifier="chevron" class="take-from-camera">
<ons-icon icon="ion-camera"></ons-icon> カメラで撮影
</ons-list-item>
</ons-list>
<br>
</ons-page>
</ons-navigator>
<ons-template id="image.html">
<ons-page id="image-page">
<ons-toolbar>
<div class="left">
<ons-back-button ons-if-platform="ios">Back</ons-back-button>
</div>
<div class="center">画像</div>
</ons-toolbar>
<ons-carousel var="imageCarousel" class="image-carousel" fullscreen auto-scroll overscrollable>
</ons-carousel>
</ons-page>
</ons-template>
</body>
</html>
ons.bootstrap()
11行目のons.bootstrap()は,Onsen UIを読み込み,Onsen UIの機能をアプリで利用できるようにする。 javascriptの一番最初に実行する。 もし,これを書かなければOnsen UIを利用した処理は動かない。なお,この関数は Onsen UI V1 Minimum (Onsen UI Version 1 最小限のプロジェクト)でなければ動かないみたい。既に Onsen UI V2 は出ているみたいだけれど動かなかった。
getPictureFromGallery()
15行目のgetPictureFromGalleryは,ギャラリーから画像のパスを取得する関数。 引数の onSuccess は成功したときに実行するコールバック関数で,実際には23行目で呼び出され,49~58行目で定義したものが実行される。 実行時,23行目に書いてあるように,引数として imageURI が渡される。 imageURIは,ギャラリーから画像のパスを取得するCordovaのAPIである navigator.camera.getPicture が成功したときに呼び出されるコールバック関数で,オプションの destinationType に Camera.DestinationType.FILE_URI を指定した場合,このコールバック関数の引数に画像ファイルへのパスが返される。getPictureFromCamera()
28行目のgetPictureFromCameraは,写真を撮影して保存する関数。 CordovaのAPIである navigator.camera.getPicture を呼び出すときのオプション sourceType が Camera.PictureSourceType.CAMERA になっているだけで,他はgetPictureFromGalleryと同じである。onFail()
CordovaのAPIである navigator.camera.getPicture が何らかの原因で失敗したときに呼び出される関数。メインページが表示されたときのイベントハンドラ
48~66行目はメインページが表示されたときのイベントハンドラ。 前述したように49~58行目にgetPictureFromGalleryやgetPictureFromCameraの引数に指定するコールバック関数が定義されている。 この関数では,引数に渡された画像ファイルのURIをsrc属性に指定したimgタグを作り,'無加工'というラベルとともにimages配列へ追加している。 ただ,このとき,50行目でこの関数に入る都度images配列を初期化しているため,何回この関数が呼び出されても配列imagesには1枚の画像しか格納されない。なぜそうなっているのかは不明。 50行目を取り除き,13行目でimagesを定義するとき空の配列 [] で初期化すれば複数の画像が配列に格納される。 60~62行目,63~65行目は,それぞれボタン「カメラで撮影」,「ギャラリーから選ぶ」がクリックされたときの呼ばれるイベントハンドラである。 ここで $(this) は,メインページを表す。一般に,イベントハンドラ内では$(this)はそのイベントを取得したオブジェクトを表す。 したがって,メインページ内でセレクタが '.take-from-camera' のオブジェクト(classプロパティにtake-from-cameraが設定されているタグ)がクリックされたとき関数getPictureFromCamera()が, '.take-from-gallery' のオブジェクトがクリックされたとき関数getPictureFromGallery()が呼び出されるようにイベントハンドラが登録される。画像ページが表示されたときのイベントハンドラ
68~83行目は画像を表示するためのページ(image-page) が表示されたときに呼び出されるイベントハンドラの定義である。
まず,69行目のimages.mapであるが,これは配列(この場合はimages)の各々の要素に対してある処理を行って,その結果から得られるデータを要素とする配列を返す関数である。
具体的には,ギャラリーから取得した,あるいは,カメラで撮影した画像を指定して50~56行目で作成したimg要素配列の各々に対して,70~73行目で画像をカルーセル表示するためのons-carousel-item要素を作成し,それを要素とする配列を変数elementsに格納している。
そうして作成した配列elementsの各々の要素を,76~78行目でons-carousel要素の子要素として加えている。
最後に80~82行目でカルーセルを0.1秒後にリフレッシュしている。ここで,81行目のimageCarouselは115行目でons-carousel要素につけた変数名である。
なお,ons-carousel要素はテキストのP161に説明があるが,左右や上下に項目を並べてスワイプで移動できるようにしたものである。詳細はオンラインマニュアルを参照のこと。
プリプロード
後で表示する画像を前もって読み込んでおき,表示するときにスムーズにすることをプリプロードという。 51~56行目でこのプリプロードを行っている。プリプロードを行うにはまずimgタグ要素を作成する(51行目)。jQueryでhtml要素を作成するには$()内にセレクタでなくhtmlタグ(この場合は<img>)を書く。このとき返される値はjQuery要素である。こうして作成されたhtmlタグ要素にattrメソッドでsrc属性に画像のurlを設定する(52行目)。
