HTML5 API の代名詞のひとつとして注目されているcanvasについて少し考え触ってみました。
canvasとはブラウザ上に画(図)を描くことのできるHTML5からサポートされたAPI。
今まではブラウザ上で画(図)を表示させるにはGIFやJPEG、PNGと言った画像フォーマットを用意する必要があったけど、このcanvasを使うことで実現可能です。
またcanvasは、FlashやJavaのプラグインを使わずに、諸々の条件やデータに応じて表示させる画(図)をインタラクティブに表示したり、アニメーションさせることが可能です。
canvasを対応しているブラウザは以下になります。(2013.11.05 現在)
プロジェクトによっては、まだまだIE8が必須ブラウザなので厳しいところ...。
canvasタグを使用して描けるものは以下のものです。
canvasのマークアップは以下の感じ。
<html lang="ja"> <head> <meta charset="UTF-8" /> <title>canvas markup</title> </head> <body> <canvas width="800" height="400"> <!-- widthが800px、heightが400pxのcanvas --> </canvas> </body> </html>
canvasはhtml側でマークアップしただけじゃ意味がないので、JavaScriptでゴリってみましょう。
sampleCanvas01.coffee
#canvas要素のノードオブジェクトを取得 _canvas = document.querySelector('canvas') # 2Dコンテキストを取得 _ctx = _canvas.getContext('2d')
canvasを使用する際には必ずおまじないに上記のコードを使用する。
sampleCanvas02.coffee
# まずはおまじない _canvas = document.querySelector('canvas') _ctx = _canvas.getContext('2d') #ここから短形を描く _ctx.fillStyle = '#ff00ff' #ピンク # x座標10、y座標20に幅200、高さ100の短形を描く _ctx.fillRect(10, 20, 200, 100) # _ctx.fillRect(x, y, w, h) # 輪郭線の色をセットする。 _ctx.strokeStyle = '#000' #黒
細かい事を説明するのもいいのですが、何か作ってみて実際に手を使って作ってみる。
以下の条件で何か作ります。
この条件で考えたのが自分はMac使いなので、対応ブラウザはGoogle Chromeで。HTML5でサポートされているデバイスのマイクを使用して、マイクの音をデータとして取得してそれをcanvasで描いてみます。 * 以下ザックリですがコメントで細かく書いております。
main.coffee
'use strict' class @Main _ctx = null _audio = null _analyser = null _filter = null _width = 0 _height = 0 constructor: -> ### * 初期化 * @method init * @public ### init: -> initCSS() _color = getRandomRGB() window.onload = -> _canvas = document.querySelector 'canvas' ### canvas対応ブラウザかどうかの確認 ### return false if not _canvas or not _canvas.getContext _ctx = _canvas.getContext('2d') _width = _canvas.width = window.innerWidth _height = _canvas.height = window.innerHeight initAudio() ### * リセットCSSの設定 * @private ### initCSS = -> _styleObjArr = [] _styleObjArr[0] = 'body, canvas { margin: 0; padding: 0;}' _doc = document if _doc.createStyleSheet _sheet = _doc.createStyleSheet() _sheet.cssText = _styleObjArr.join('') _sheet = undefined else _style = _doc.createElement('style') _style.textContent = _styleObjArr.join('') _head = _doc.getElementsByTagName('head')[0] _head.appendChild _style _style = undefined _head = undefined _doc = undefined ### * webkitaudioの初期化 * @private ### initAudio = -> _audio = new webkitAudioContext() _filter = _audio.createBiquadFilter() _filter.type = 0 _filter.frequency.value = 440 _analyser = _audio.createAnalyser() setupMic() ### * マイクの設定 * @private ### setupMic = -> _audioParam = audio: true _navi = navigator ### マイクデバイスがあるか ### if _navi.webkitGetUserMedia _navi.webkitGetUserMedia _audioParam, success, onError else alert 'no mic, go to Amazon!' _navi = undefined ### * マイク接続に成功したら(WebAudioリクエストに成功したら) * @param stream * @private ### success = (stream) -> ### audioNodeの作成 ### _mediaStream = _audio.createMediaStreamSource(stream) ### 出力Nodeのdestinationに接続 (Flashでmic使う時にmediaに接続するのと同じ)### _mediaStream.connect _filter _filter.connect _analyser draw() ### * 描画 * @private ### draw = -> ### 既に描画されてるかもだからclearしておく ### _ctx.clearRect(0, 0, _width, _height) _bg = _ctx.createLinearGradient(0, 0, 0, _height) _bg.addColorStop(0, '#000000') _bg.addColorStop(1, '#333333') _ctx.fillStyle = _bg _bg = undefined _ctx.fillRect(0, 0, _width, _height) ### ByteArrayの作成 ### _ba = new Uint8Array(_analyser.frequencyBinCount) ### 周波数の取得 ### _analyser.getByteFrequencyData(_ba) _ctx.fillStyle = _color _i = -1 _length = _ba.length while ++_i < _length ### 上 ### _ctx.fillRect _i << 1, 0, 5, _ba[_i] << 1 ### 下 ### _ctx.fillRect _i << 1, _height, 5, ~((_ba[_i] << 1) + 1) requestAnimationFrame(draw) _ba = undefined ### * ランダムなRGB値を返します * @return {String} ### getRandomRGB = -> return '#' + ('00000' + (Math.random() * (1 << 24) | 0).toString(16)).slice(-6) ### * エラー * @event error event * @private ### onError = (event) -> alert('Web Audio error :: ' + event.code)
これをコンパイルしてサーバーにアップしておきました。 こちらからどうぞ。
canvasは、JavaScriptでゴニョゴニョしないと本来の力が発揮されないと思います。
が、JSでdivとかをいじるより、遥かに処理能力的にものすごく軽いです。
対応ブラウザを気にしないなら一昔前のFlashサイトの用な事まで可能だと思います。
またcanvas APIの使い方自体がActionScripに似ているので、Flasherには学習コストが低いと思います。
もちろん、そもそもがJavaScriptという一般的に使われるケースが多いスクリプトなので、Flasherじゃない人でもコードを参考にしながら美しく早いcanvasの実装が可能だと思います。
ただ、実務ベースのプロジェクトになると、その案件の対象ブラウザを気にしなくてはなりません。単にcanvasオンリーなサイトと言う訳には行かなさそうです。
どうしても実務ベースで使いたい!となれば、canvasを無理やり対応させるライブラリを使用するとか、ブラウザ分岐する処理がまだ必須な気がしますが、スマートフォンでの閲覧が圧倒的に増えてきているイマ、ユーザの状況を考慮すると、導入していく価値は十二分にある気がしています。