このページの本文へ

PROGRAMMING 古籏一浩のJavaScriptラボ ― 第64回

Canvasで作ったWebアプリをiPhoneアプリに変換

2011年07月11日 13時00分更新

古籏一浩

  • この記事をはてなブックマークに追加
本文印刷
js-labo

 HTML/CSS+JavaScriptでiPhone/iPadアプリを開発できるNimbleKit。前回まではNimbleKit独自のAPIを使ってアプリを開発する方法を紹介してきましたが、NimbleKitを使うとHTML/CSS+JavaScriptで作ったWebアプリケーションもiOSアプリとしてパッケージ化できます。NimbleKit編の最終回は、HTML5 Canvasを使ったお絵かきツール「シンプルペイント」をiPhoneアプリに変換する方法を紹介します。

古籏一浩のJavaScriptラボ 第31回「HTML5のCanvasで作る、Flash不要のお絵かきツール」
http://ascii.jp/elem/000/000/513/513377/

 シンプルペイントはPCのブラウザー向けに作ったWebアプリですので、iPhone/NimbleKitでは実装が難しい機能もあります。そこでiPhoneアプリにするにあたって、以下の点を変更します。

  • iPhoneの画面サイズに合わせてCanvasの描画領域を調整
  • ブラシサイズは固定
  • ブラシのカラーはNimbleKitのスライダーで設定可能
  • 設定したブラシのカラーは自動的にプレファレンス(設定)に保存。次回起動時にカラー設定を復元

最低限の機能を移植する

 最初に、シンプルペイントのHTMLをiPhone用に変更します。canvas要素のwidth属性とheight属性でCanvasの描画領域を320×320pxに設定し、canvas要素の下に描画色を示すカラーバー領域をdiv要素で用意します。HTMLの最後に、script要素でシンプルペイントのメイン処理を記述したスクリプト「draw.js」 を読み込ませます。draw.jsファイルはこれまで同様、Resourcesフォルダに入れておきましょう。

【図】1.png
draw.jsはXcodeのResourcesに入れておく

 draw.jsは、第31回で掲載したサンプルから保存機能やブラシのカラー選択機能を削除したものです。iPhoneではイベントオブジェクトのtouches配列に、タッチされた座標が入っていますので、X,Y座標を求める処理を以下のように変更しています。pageX, pageYはページの左上を基準にした座標です。

●PC用

var x = e.clientX;
var y = e.clientY;

●iPhone/iPad用

var x = e.touches[0].pageX;
var y = e.touches[0].pageY;

 標準では画面上をドラッグするとページがスクロールしてしまうので、以下のスクリプトを追加して画面を固定します。

document.ontouchmove = function(evt){
  evt.preventDefault();
}

 ここまでをまとめたのがサンプル1です。Canvas上を指でなぞると赤い線で絵が描けます。

【図】2.png 【図】3.png

■サンプル1[HTML]

<html>
<head>
<meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="NKit.js"></script>
<style>
body { margin:0; padding: 0; background-color:black; }
canvas { background-color: white; }
</style>
</head>
<body>
<canvas id="myCanvas" width="320" height="320"></canvas>
<div id="stat"></div>
<script type="text/javascript" src="js/draw.js"></script>
</body>
</html>

■サンプル1[draw.js]

var drawData = {
  drawFlag : false,
  oldX : 0, // 直前のX座標を保存するためのもの
  oldY : 0, // 直前のY座標を保存するためのもの
  brushSize : 4// ブラシサイズ
  penColor : "rgba(255,0,0,1)"
}
var can = document.getElementById("myCanvas");
can.addEventListener("touchmove", function draw(e){
  if (!drawData.drawFlag) return;
  var x = e.touches[0].pageX;
  var y = e.touches[0].pageY;
  document.getElementById("stat").innerHTML = drawData.oldX+","+drawData.oldY;
  var can = document.getElementById("myCanvas");
  var context = can.getContext("2d");
  context.strokeStyle = drawData.penColor;
  context.lineWidth = drawData.brushSize;
  context.lineJoin= "round"// 連結部分を丸にする
  context.lineCap = "round";
  context.beginPath();
  context.moveTo(drawData.oldX, drawData.oldY);
  context.lineTo(x, y);
  context.stroke();
  context.closePath();
  drawData.oldX = x;
  drawData.oldY = y;
}, true);
can.addEventListener("touchstart", function(e){
  drawData.drawFlag = true;
  drawData.oldX = e.touches[0].pageX;
  drawData.oldY = e.touches[0].pageY;
  document.getElementById("stat").innerHTML = drawData.oldX+","+drawData.oldY;
}, true);
can.addEventListener("touchend", function(){
  drawData.drawFlag = false;
}, true);
// デフォルトのイベントを禁止
document.ontouchmove = function(evt){
  evt.preventDefault();
}

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

HTMLリファレンス誘導バナー

CSSリファレンスサイト誘導バナー

Webディレクター江口明日香が行く

ランキング