必見の記事

iOS6のSafariでサポートされるHTML5の機能

2012.09.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

以前、HTML5でカメラやGPSなどスマートフォンならではの機能がどこまで使えるのか調べました。
最近、iPhone5を買ったので今度はiOS6のSafariでサポートされたHTML5の機能を試して見ようと思います。

試したのは以下の5つです。iPhoneで確認できるようにサンプルを作ったので試してみて下さい。

■ファイルアクセス(File API)とカメラ(HTML Media Capture)

ファイルアクセスとカメラ連携のサンプルです。iOS6ではFile APIの書き方でカメラも使えました。
[ファイルを選択]ボタンを押すと以下の画面になります。


写真またはビデオを撮る → カメラアプリが起動します。
既存の項目を選択    → ファイル選択画面に遷移します。Internal Storageの中のファイルを選択できます。
ボタンを押して即、カメラ起動というのはできませんでした。

File APIのサンプル

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="initial-scale=1.0" />
		<title>File APIサンプル</title>
		<script>
			window.addEventListener("load", function(){
				
				if (!window.File){
					result.innerHTML = "File API 使用不可";
					return;
				}
				
				document.getElementById("imageFile").addEventListener("change", function(){
					var reader = new FileReader();
					
					reader.onload = function(event){
						document.getElementById("image").src = reader.result;
					}
					var file = document.getElementById("imageFile").files[0];
					reader.readAsDataURL(file);
				}, true);
			}, true);
		</script>
	</head>
	
	<body>
		<form>
			<input type="file" accept="image/*" id="imageFile"/>
		</form>
		<img id="image"width="200" height="200">
		<div id="result"/>
	</body>
</html>

inputタグにmultiple属性を追加して、

<input type="file" accept="image/*" id="imageFile" multiple/>

にするとボタンタップ時に以下のような画面に遷移してファイルを複数選択できます。
この場合は撮影はできません。
File APIのサンプル(ファイル複数選択)

■音声処理・合成(Web Audio API)

Web Audio APIに関しては以下のサイトに書いてありました。
Web Audio APIをつかった音声処理

上記のサイトを参考にしてボタンを押すと音声を出力する簡単なサンプルを作ってみました。
Playボタンを何回か押すと音を重ねることができます。ボリュームも調節可能です。
この音声を出力するだけであればaudioタグでもできると思いますが、Web Audio APIは音声ファイルの生成も可能です。
今のところモバイルブラウザでサポートしているのはiOS6のSafariのみです。
iPhoneの場合はハードウェアでもボリュームの調節ができました。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1.0" />
		<title>Web Audio APIサンプル</title>
		<script src="js/buffer-loader.js"></script>
		<script>
		
			window.addEventListener("load", function(){
				
				var context = new webkitAudioContext();
				var bufferLoader = new BufferLoader(context,['./sample1.mp3'], function(){});
				var gainNode = context.createGainNode();
				var volume = document.getElementById('volume');
				
				document.getElementById("play").addEventListener("click", function(){
					var source = context.createBufferSource();
					source.buffer = bufferLoader.bufferList[0];
					
					source.connect(gainNode);
					gainNode.gain.value = volume.valueAsNumber;
					gainNode.connect(context.destination);
					
					source.connect(context.destination);
					source.noteOn(0);
                }, true);
                
				volume.addEventListener("change", function(){
					gainNode.gain.value = this.valueAsNumber;
                }, true);
                
                bufferLoader.load();
			}, true);
        </script>
	</head>
	<body>
		<form>
			<input type="button" id="play" value="Play"/>
			volume:<input id="volume" type="range" value="0.5" max="1" min="0" step="0.1"/>
        </form>
	</body>
</html>

■アニメーション(Animation Timing API)

Canvas上の線が伸びていくだけの簡単なアニメーションのサンプルです。1フレームごとに縦横1ピクセル伸ばしています。
requestAnimationFrameの引数にrequestAnimationFrameを含めたファンクションを代入することでループさせています。
setInterval使ってループさせるよりもパフォーマンスがいいそうです。

Animation Timing APIのサンプル

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<title>Animation Timing APIサンプル</title>
		<script>
			var context;
			var lineTo = 0;
			var requestAnimationFrame;
			
			window.addEventListener("load", function(){
				var canvas = document.getElementById('canvas') ;
				context = canvas.getContext('2d');
				requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame
					|| window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
					|| window.oRequestAnimationFrame ;
				animationLoop();
			}, true);
			
			function animationLoop() {
				lineTo++;
				context.beginPath();
				context.moveTo(0, 0);
				context.lineTo(lineTo, lineTo);
				context.lineWidth = 10;
				context.stroke();
				requestAnimationFrame(animationLoop) ;
			}
		</script>
	</head>
	<body>
		<canvas id='canvas' width="1000px" height="1000px"/>
	</body>
</html>

■CSS Filter Effects

CSSだけで画像にフィルターをかけることができるようになりました。
サンプルではCSS3のアニメーションを使って画像が徐々にセピア色になっていくようにしました。
-webkit-filterに指定できるフィルターの種類としては

  • brightness:輝度
  • contrast:コントラスト
  • saturate:彩度
  • opacity:不透明度
  • grayscale:グレースケール
  • drop-shadow:ドロップシャドー
  • blur:ぼかし

などがあります。他にもありますので興味がある方は調べてみて下さい。
これでカメラで撮った写真をその場で加工する、といったWebアプリも作れそうですね。

CSS Filter Effects

<!DOCTYPE html>
<html>
	<head>
	<meta charset="utf-8">
	<meta name="viewport" content="initial-scale=1.0" />
	<title>CSS Filter Effectsサンプル</title>
	<style>
		@-webkit-keyframes sample {
		  from { -webkit-filter: sepia(0); }
		  to   { -webkit-filter: sepia(1); }
		}
		
		.sepia {
		  -webkit-animation-name: sample;
		  -webkit-animation-duration: 5s;
		  -webkit-animation-iteration-count: infinite;
		  -webkit-animation-direction: normal;
		  -webkit-animation-timing-function: linear;
		}
	</style>
	
	</head>
	<body>
		<img id="image" width="200px" height="200px" src="./sample.jpg" class="sepia">
	</body>
</html>

■Remote Debugger

APIではありませんが、iPhoneを接続したPC上でデバッグできるようになりました。
試しにブレークポイントを置いてデバッグしてみました。Safari 6が必要なのでWindowsではデバッグできません。
デバッグするにはWebインスペクタというツールを使います。Webインスペクタに関しては以下のページに書いてあります。
iOS6 Mobile SafariがAjax POSTでキャッシュする問題を回避する方法

WebインスペクタにはiPhoneのSafariで表示しているページのソースが表示されていますので、
ボタンタップのイベントハンドラ内にブレークポイントを配置してから、iPhoneを操作したところ止めることができました。
Webインスペクタの見た目がXcodeと似ていることもあり、実機を使ってネイティブアプリ開発するのと近い感じでできました。

注意点:
WebインスペクタはSafariの開発メニューから起動しますが、
開発メニューが表示されていない場合はSafariの設定でにチェックを入れます。

調べたことは以上になります。これ以外にもiOS6のSafariでサポートされる機能があるのですが今回はHTML5関連に絞って調査しました。
これからも引き続きモバイルブラウザでHTML5を調べていこうと思います。

■関連サイト

HTML5で使えるスマートフォンの機能
スマートフォンサイトのパフォーマンスチューニング