本文へジャンプ

HTML5 APIの代名詞! canvasについて(基本編)

Posted by MD

HTML5 API の代名詞のひとつとして注目されているcanvasについて少し考え触ってみました。

canvasとは?

canvasとはブラウザ上に画(図)を描くことのできるHTML5からサポートされたAPI。
今まではブラウザ上で画(図)を表示させるにはGIFやJPEG、PNGと言った画像フォーマットを用意する必要があったけど、このcanvasを使うことで実現可能です。

またcanvasは、FlashやJavaのプラグインを使わずに、諸々の条件やデータに応じて表示させる画(図)をインタラクティブに表示したり、アニメーションさせることが可能です。

対応ブラウザ

canvasを対応しているブラウザは以下になります。(2013.11.05 現在)

  • Google Chrome
  • Firefox
  • safari
  • IE9以上

プロジェクトによっては、まだまだIE8が必須ブラウザなので厳しいところ...。

canvasで描けるもの

canvasタグを使用して描けるものは以下のものです。

  • 図形(矩形、円、角丸、多角形)
  • パス(直線、円弧、曲線)
  • テキスト
  • 画像
  • シャドウ
  • 色(塗りつぶし、ストローク)

canvasの座標

  • 左上が(0, 0) Flashと同じ
  • 右がx座標
  • 下がy座標
  • 座標は、ピクセルの中心ではない。グリッドの境界を表す。(左上が始点)

canvasのマークアップ

canvasのマークアップは以下の感じ。




canvas markup







canvasをJSでいじってみる

canvasはhtml側でマークアップしただけじゃ意味がないので、JavaScriptでゴリってみましょう。

まずはcanvasの初期設定

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' #黒  

canvasを使って何か作ってみる

細かい事を説明するのもいいのですが、何か作ってみて実際に手を使って作ってみる。
以下の条件で何か作ります。

  • ブラウザは気にしない(今回はGoogle Chrome)
  • インタラクティブなもの。
  • アニメーションさせる。
  • 仕事道具の指を負傷しているので極力タイピングしないw

この条件で考えたのが自分は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)

これをコンパイルしてサーバーにアップしておきました。 こちらからどうぞ。

こんな感じになります。
Sample - HTML5 canvas API

まとめ

canvasは、JavaScriptでゴニョゴニョしないと本来の力が発揮されないと思います。
が、JSでdivとかをいじるより、遥かに処理能力的にものすごく軽いです。
対応ブラウザを気にしないなら一昔前のFlashサイトの用な事まで可能だと思います。
またcanvas APIの使い方自体がActionScripに似ているので、Flasherには学習コストが低いと思います。
もちろん、そもそもがJavaScriptという一般的に使われるケースが多いスクリプトなので、Flasherじゃない人でもコードを参考にしながら美しく早いcanvasの実装が可能だと思います。

ただ、実務ベースのプロジェクトになると、その案件の対象ブラウザを気にしなくてはなりません。単にcanvasオンリーなサイトと言う訳には行かなさそうです。
どうしても実務ベースで使いたい!となれば、canvasを無理やり対応させるライブラリを使用するとか、ブラウザ分岐する処理がまだ必須な気がしますが、スマートフォンでの閲覧が圧倒的に増えてきているイマ、ユーザの状況を考慮すると、導入していく価値は十二分にある気がしています。

FRESHERS WANTED!
Recent Entries
MD EVENT REPORT
What's Hot?
日本各地の酒蔵との直取引により厳選して仕入れた日本酒を世界に販売
こんな僕たちの仲間に入りませんか?
Movable Type AWS 移管&アップグレード サービス
SNS・ブログ・メールからの流入数が一目でわかる
2018年度 新卒採用 Webデザイナー/エンジニア、プロデューサー/ディレクター募集
50,000円からのシネマグラフ(Cinemagraph)制作
TAKUYAが教えるギター・レッスン
KenKenが教えるベースギター教則アプリ
SNS連動型クチコミ拡散システム「レビュー ジェネレーター サービス」
1時間1万円の撮影スタジオ
Share this on
Facebook Twitter Google+