タグ別アーカイブ: HTML5j

HTML5 Canvas:円を描く時のパフォーマンス

この記事はHTML5 Advent Calendar 2012の13日目のエントリーになります。

Canvasのクリスマスツリーもう少しでクリスマスなので、HTML5 の canvas でクリスマスツリーに飾り玉を描こうかなと思いました。色んな方法を考えながら、Stack Overflow に「円を円形グラデーションだけで描けるよ」というコメントを見つけました。

ご存知だと思いますが、canvas で円を描くには普通 arc()を使います:

// 普通の円の描き方
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
ctx.fillStyle = 'rgba(195, 56, 56, 1)';
ctx.fill();
ctx.closePath();

例えば SVG と比べるとちょっと面倒くさい感じがするかも知れません。円形グラデーションを使うのが良いアイディアと思い、それぞれのやり方のパフォーマンスの違いが知りたくなりました。

// 円形グラデーションで円の描き方
var gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0.95, 'rgba(195, 56, 56, 1)');
gradient.addColorStop(1, 'rgba(195, 56, 56, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(x - radius, y - radius, x + radius, y + radius);

この canvas テストページで速さの違いが実際に見えます。

やっぱり arc() より円形グラデーションの方が遅いです。何倍も遅い!テストページを作る前、これに気付くべきでしたが、まぁ、どうせなので3Dっぽい球の描き方も調べる気になりました。

Canvas で球を描くには主に二つの方法があります:

  1. 円形グラデーションを利用する
  2. 既存の画像を利用する
// 円形グラデーションでの描き方
var gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(0.2, 'rgba(255, 85, 85, 1)');
gradient.addColorStop(0.95, 'rgba(128, 0, 0, 1)');
gradient.addColorStop(1, 'rgba(128, 0, 0, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(x - radius, y - radius, x + radius, y + radius);
// 既存の画像での描き方
var img = new Image();
img.src = 'images/baubles.png';
ctx.drawImage(img, x, y, width, height);

先ほどと同じように円形グラデーションの方が数倍遅いみたいです。しかし円形グラデーションの利点はもちろんその効果が動的に作られているため、JavaScript で変更することができます。一方画像を使う場合、ソフトで画像を前もって作る必要があります。JavaScript での編集ができませんが、大きさなら変更できます。色を変更したい時はこの二つの方法のいずれかが使えます:

  1. 複数バージョンのある sprite 画像を利用する。
  2. 白黒の画像を利用し、arc() で半透明のオーバーレイを適用する。

ところで画像のダウンロード時間も忘れてはいけませんので、ユーザを待たせないように画像のプリロード(先読み)がおすすめです。

前述の canvas テストページでそれぞれの速さの比較ができます。

テストから分かるように、半透明オーバーレイの方法は少し遅いですが、色の変更がもっと自由にできます。ただ、元々の画像よりコントラストが少し悪くなります。我慢できる位であるかどうかは皆様にお任せします!。

まとめ

結局簡単なアプリや力のあるデバイスなら速さの違いは気付く程ではないかも知れませんが、アニメーションを使う時、高速ゲームを作る時、もしくはTV用のアプリを作る時、パフォーマンスが重要になります。色々な選択肢がありますので、私からのアドバイスは下記の通りです:

  • 円が描きたい時、arc()を使いましょう。
  • 3Dっぽい球が描きたい時、画像を使いましょう(プリロードを忘れずに)。
  • 色んな色の球が描きたい時、sprite 画像を使いましょう。
  • 動的に色が変わる球が描きたい時、半透明オーバーレイのある画像を使ってみましょう。
  • 円形グラデーションは必要な時だけに使いましょう。

最後にもう一つ学んだことですが、やっぱり数千個の飾り玉のあるクリスマスツリーはオシャレじゃない!

更新:

TwitterでMarceloさんが良いアイディアをつぶやきました。隠されているcanvasに円形グラデーションで円を描いて、それをdrawImage()で元々のcanvasに数回描くというアイディアでした。これで画像を前もって作る必要がないし、動的に色を変えることも可能です。しかも既存画像にdrawImage()を使うよりもパフォーマンスが良いです!(円形グラデーションの描く時間を除けば。)コードはこんな感じです:

// いわゆる「バッファー」canvasを作るけど、ページに追加しない
var tmpCanvas = document.createElement('canvas');
var tmpCtx = tmpCanvas.getContext('2d');

// ここで必要なグラデーションを用意する(上記のサンプルみたいに)

// さきほどの「バッファー」canvasから元々のcanvasに描く
ctx.drawImage(tmpCanvas, x, y, width, height);

つまり、円や玉をたくさん描く時はこの方法が一番お勧めです。Marceloさん、サンキュー!

HTML5、CSS3 で作るポラロイド風写真

HTML5 Advent Calendar の12日目です。
本来のAdvent Calendarとは、12月1日からクリスマスの25日まで、カードに作られた窓を1日に1つずつ開けていくというものです。一方、技術系の Advent Calendar は、12月1日から25日までの間、毎日違う人が特定のテーマに沿ってブログ記事を書くというものです。ここでは、「HTML5」がテーマになります。他にも面白い記事が公開される予定ですので興味のある方は是非チェックしてみてください:http://atnd.org/events/21987

五つのステップでブログとかに活用できるポラロイド風の写真を HTML5 と CSS3 で作りたいと思います。似たサンプルがあっちこっちにありますが、もう少し本物っぽくなるように第5段階でアニメーションの追加があります。
完成すればこういうふうになります: HTML5、CSS3 のポラロイド風写真

さぁ、スタートしましょう!

1. まずは HTML5

ポラロイド風写真その1最初にマークアップを用意しましょう。HTML5 ではいくつかの新しい要素があります。どれをどういうふうに使うかは混乱しやすいですが、一つの簡単な要素は <figure> です。画像かビデオに使う要素で、実はそれだけであまり利点がなさそうですが、画像やビデオに説明の文章がある場合、<figcaption> との併用で役立ちます。使い方はこんな感じです:

<!-- HTML ファイル -->
<figure id="polaroid">
  <img src="santa.jpg" alt="本物のサンタさん">
  <figcaption>Merry Christmas !</figcaption>
</figure>

現在のブラウザはこれで満足していますが、IE の古いバージョンでは HTML5 要素に CSS の摘要できません。解決方法の一つは Remy Sharp 氏が作った簡単な JavaScript です:

<!-- HTML ファイル -->
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

2. 次はポラロイド風に

ポラロイド風写真その2ポラロイド写真のような効果はもちろん白い紙が必要なので、画像の周りにマージンを追加し、背景を白にします:

/* CSS ファイル */
#polaroid {
  background: #fff;
  color: #111;
  display: block;
  height: 425px;
  margin: 2em auto;
  width: 350px;
}
#polaroid img {
  border: solid 1px #ddd;
  margin: 24px;
}
#polaroid figcaption {
  display: block;
  font-size: 32px;
  line-height: 1;
  text-align: center;
}

ところで、HTML5 パーサーの入っていないブラウザは <figure><figcaption> みたいな要素が認識されず、インライン要素として扱われます。そのため、display: block; を指定します。そうすると、IE6 でもポラロイドっぽく見えます。

3. CSS3 で面白く

ポラロイド風写真その3やっと CSS3 の番になりました。細かい効果を追加するともう少し本格的になります。例えば影の引用、少しの回転、そして角を微妙に丸くしましょう:

/* CSS ファイル */
#polaroid {
  box-shadow: 0 2px 4px #777;
  border-radius: 3px;
  -webkit-transform: rotate(5deg);
  -moz-transform: rotate(5deg);
  -ms-transform: rotate(5deg);
  -o-transform: rotate(5deg);
  transform: rotate(5deg);
}

多くの CSS3 プロパティの長所は古いブラウザで表示されなくてもデザインが崩れることは殆どありません。ただ、最も最新のプロパティができるだけ多くのブラウザで表示されるように、上記みたいにベンダープレフィックスが必要になります。

4. 一言メッセージをおしゃれに

ポラロイド風写真その4今のところ、結構完成に近い感じがしますが、画像の下にあるメモはメモらしくないですね。ここでウェブフォントを使いましょう。ウェブフォントを使う時はもちろん利用する許可が必要です。このデモに使うフォントは Jesús Gorriti がコピーライト無しで公開している Gorri Sans です。

ウェブフォントは IE6 を含めてたくさんのブラウザで使うことができますが、ちょっとしたコツが必要です。Paul Irish 氏、Richard Fink 氏や Ethan Dunham 氏が色んな環境でテストして、一つの結果としてはこのコードがあります:

/* CSS ファイル */
@font-face {
  /* Font source: http://gorriti.com/2009/02/05/mi-aportacion-al-mundo-brutista/ */
  font-family: 'GorriSans';
  src: url('GorriSans.eot?') format('eot'), url('GorriSans.woff') format('woff'), url('GorriSans.ttf') format('truetype');
}
#polaroid figcaption {
  font-family: GorriSans, arial, sans-serif;
}

因みに上記のフォントフォーマット(EOT式、WOFF式など)への変換は、Font Squirrel の @font-face ジェネレーターをおすすめします。

5. フェードイン効果の追加

いよいよ最後の仕上げになりましたが、それはもちろん写真の現像です。本物のポラロイド写真みたいに、このデモの写真が目の前でゆっくりと現れます。JavaScript を使うことが可能ですが、CSS のみの方法でやってみましょう。アニメーションそのものは簡単であり、画像の透明度にトランジションを利用します。つまり、1分の間、opacity が 0(透明)から 1(不透明)に変わります。

どのトランジションでも、二つ以上の状態が必要です。この場合、ページ自体が第1状態になり、第2状態を作るには target の疑似要素(pseudo-element)を使います。トランジションを起動するには、<body> 要素に「demo」という ID を加え、ページの URL にも「#demo」を追加します。そうすると、ページがロードする時、画像が透明の状態から段々画像が見える target の状態に変わります。

<!-- HTML ファイル -->
<body id="demo">
  ...
</body>

/* CSS ファイル */
#polaroid img {
  opacity: 0;
  -webkit-transition-duration: 60s;
  -moz-transition-duration: 60s;
  -ms-transition-duration: 60s;
  -o-transition-duration: 60s;
  transition-duration: 60s;
}
#demo:target #polaroid img {
  opacity: 1;
}

完成したデモ: kyokodaniel.com/tech/css3/polaroid/index.html#demo

さぁ、これで更にクリスマスの雰囲気になったでしょうか?来年の HTML5、CSS3などのウェブ技術の発展が楽しみですね。皆さん、have a Merry Christmas and a Happy New Year!

JavaScript を勉強すべきか

JavaScript を勉強しましょう昨日はあるソフト開発会社と HTML5 についてとても面白い話ができました。HTML5 はもちろんバズワードで注目されているものですが、ある面では HTML5 の新しい技術の知識より JavaScript の知識の方が重要であるかも知れません。私が前から思っていたことの一つは、 HTML や CSS を利用しているWebデザイナーが JavaScript を少しでも勉強しないと仕事がなくなる恐れがある、ということです。しかし、昨日の話のおかげでWebアプリケーションが人気になればなるほど、いわゆる一般的な開発者も JavaScript を勉強する必要性が出てくると気づきました。いつも C++ を使っているプログラマーでも、いつも Photoshop を使っているデザイナーでも、JavaScript を理解するためのキーポイントは同じです:

  • JavaScript を使う前に詳しく勉強する必要はありません。一行でもホームページに挿入して試してみることができます。
  • JavaScript は厳しくないです。いろんな間違いを許してくれます。例えば、変数の宣言を忘れたり、セミコロンを忘れたり。
  • コーディングしやすい言語です。例えば、変数のタイプは指定しません。
  • 一応安全な言語です。どうすれば良いか分からない時、何でも試してみても大丈夫です。最悪の場合、ブラウザの再起動が必要になります。
  • 開発ツールがあります。最も簡単なのは OperaFirefox に入っているエラーコンソールです。ちゃんとしたデバグツールなら Opera の DragonflyFirefox の Firebug がお勧めです。開発用の IDE がほしい方は Eclipse (英語)や Aptana(英語)が利用できます。

しかし、私にとって最も重要なポイントは:

  • JavaScript のパワーです。以前はくだらないアニメーションによく使われていましたが、その時代は終わりました。成長しました。

JavaScript と他のWeb言語(HTML、CSSなど)でできるものは C++、Javaなどでできるものに急速に近づいてきています。jQuery みたいなライブラリーのおかげでその差がますます小さくなっています。一般的な開発言語との概念はほぼ一緒ですが、異なるところはプラットフォームです。ネットワークを利用するデバイスが多くなればおおくなるほど、OS のための開発よりブラウザのための開発の方が一般的になるでしょう。

参考資料

プログラミング経験がない場合:

プログラミング経験がある場合:

お勧めの本

最後に、Opera 社員でいることにも関わらず、Mozilla さんの JavaScript ガイドリファレンススタイルガイドはプログラミングしながらのとても役に立つ資料です。

Modernizr で HTML5 の使用が楽に

Modernizr「それぞれのブラウザはどこまで HTML5 を対応していますか。比較表はありますか。」
最近よく聞かれます。聞かれると最初の反応は「oh no!」です。

ブラウザの対応を調べようとすると、このような問題が出てしまいます:

  • ブラウザのバージョンは日々変わっています。
  • HTML5 仕様そのものは日々変わっています。
  • あるブラウザは、今日の◯◯版の対応は昨日の◯◯版の対応と違うかもしれません。
  • あるブラウザの Windows 版の対応は Mac 版、Linux 版、携帯版、テレビ版、ゲーム機版やタブレット版の対応と違うかもしれません。
  • HTML5 対応は true/false ではなく、部分的な対応の方が普通です。
  • 既存の比較表は例外がとても多く、分かりづらいです。
  • ユーザーエージェントはよく嘘を付き、ブラウザの判断としては理想的ではありません。

比較表をいつも更新するのは限りがない作業で大変だし、比較表をいつも参照しないといけないウェブ開発者がかわいそうです。この道を辿ればストレスが溜まりアッという間に白髪が増えてしまいます。おかげさまで楽な方法があります:

ブラウザの対応ではなく、使いたい機能の対応を調べましょう

JavaScript を利用すればある要素、若しくはある属性の存在を調べることができます。このための関数を作ることは難しくありませんが、便利な HTML5 や CSS3 の対応が検出できるライブラリーは既にあります: Modernizr

Modernizr は開発中のため、SVG や Opera 10.5 のトランジションとトランスフォームの検出はまだできませんが、HTML5 がすぐに使いたいウェブ開発者にお勧めです。残念ながら日本語の資料はまだ少ないようなので、使い方を簡単に説明したいと思います。

他の JavaScript ライブラリーと同じように、まずウェブページの <head> にリンクを挿入します:

<!-- HTML -->
<script src="modernizr-1.1.min.js"></script>

次は使いたい HTML5 の機能を対応しないブラウザのためのコードを書きます。JavaScript を対応しないブラウザや JavaScript を無効にしているユーザーのため、ベーシックな HTML だけを利用します:

<!-- HTML -->
<select id="level">
<option disabled selected>選択してください</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>

実際に使いたい機能(例えば HTML5 Forms の「range」スライダー)の対応は下記のように Modernizr のオブジェクトで判断できます:

// JavaScript
if (Modernizr.inputtypes.range) {
    ...
}

ブラウザが対応する場合、不必要になった要素を削除し、使いたい要素をページに追加します:

// JavaScript
var fieldset = document.getElementById('fieldset');

// 不必要なセレクトボックスを削除する
fieldset.removeChild(document.getElementById('level'));

// スライダーの input を作る
var level = document.createElement('input');
level.setAttribute('id', 'level');
level.setAttribute('type', 'range');
fieldset.appendChild(level);

上記のコードを利用して簡単なサンプルを作りました: HTML5 対応を判断するサンプル

このような方法で行うと、過去のブラウザでも、未来のブラウザでもユーザビリティが良く、そして常に変化している HTML5 のサポートを気にする必要はありません。是非機能の対応を判断しながら HTML5 を使ってみて下さい。

HTML5 についての Q&A

HTML5のよくある質問Q) HTML5とは何でしょうか?

A) HTML5 は二つに分けることができます。まずは仕様です。ホームページ作成に使う基本言語の第5版。そして、同時に出ている幾つかのウェブ関連の技術を代表する総合的な単語でもあります。例えば、Web Sockets、ジオロケーション、オフラインストレージ等。CSS、SVG や他のオープンスタンダートと同じように、ウェブを利用する時のエクスペリエンスを改善するのが目標です。

Q) 目標と言えば、HTML5 の目標はなんでしょうか。

A) 主に2つの重要な概念があります。1つは HTML を動的にすることです。今までは HTML と言えば文字、リンクと画像のみでしたが、これだけではなく、現在プラグインでしかできないこともできるようになります。もう1つの目標は HTML をなるべく使いやすくすることです。これを実現するには上位互換性をできる限り保ち、多くのウェブ開発者の開発方法に沿った基準を作ります。この方法は「”paving the cowpaths” – 牛の通り道を舗装する」と呼ばれています。

Q) それはどういう意味ですか?

A) この10年間はウェブが非常に進化しましたが、ウェブページの作り方と構成はそれほど大きく変わっていません。基準を守らないウェブページも少なくありません。現状を改善するには、ウェブ開発者の開発方法を変えようとするより、その多くの開発方法を基準にしようとしています。例えば、従来の HTML ではビデオ再生用のプラグインをウェブページに挿入すれば、そのページは非準拠になってしまいます。HTML5 は <embed> の要素が追加されましたので、その恐れがなくなりました。他にも例があります。現在、あるページは HTML で作られており、あるページは XHTML で作られています。あるページは大文字を利用し、あるページは小文字を利用しています。HTML5 ではどちらも有効です。

ただ基準を宣言するだけではなく、HTML5 は今のウェブの現状から離れないようにしようとしています。例えば、多くのウェブページはヘッダーとフッターがありますので、<header><footer> という要素が HTML5 に追加されました。同じように多くのウェブ開発者は JavaScript を使ってフォームのスライダーやカレンダー等を作るのに苦労してきましたが、これらも HTML5 の一部になりました。ウェブ利用者にとっても、いろいろなホームページにてフォームを使う際に、統一されたエクスペリエンスを感じることができます。

Q) ということは、HTML5 を使うには別の言語を学ばなくてよいのでしょうか?

A) その通りです。今までの HTML に非常によく似ていますので、既存のページが有効な HTML 又は XHTML であれば、それは有効な HTML5 となるでしょう。もしそうならなくても、通常は少ない修正で十分でしょう。もちろん、HTML5 ではなく従来のバージョンが良いのであれば更新する必要はありません。

Q) ページが有効であるかどうかはどうやって分かりますか。

A) ウェブ標準化団体の W3C はオンライン確認ツールがあります: validator.w3.org

Q) ちょっと待って!従来のバージョンと次のバージョンは違いが多くないのであれば、HTML5 の新しい基準はなんの意味があるでしょうか。

A) それがポイントです。言語の基本は似ていますが、面白いことはその基本の上にできるものです。

Q) 例えば?

A) まず新しい要素ができました。例えばよく使えそうな上記の <header> と <footer>、ナビゲーション <nav>、部分の <section> 等。その上、ウェブアプリケーションに対応できるようになりました。例えば:

  • <canvas> の要素:JavaScript を利用してウェブページの中に画像を作成。
  • <video> と <audio> の要素:プラグインを使わずビデオとオーディオを再生。
  • Web Forms 2:メール、URL、日付の入力が簡単にできるフォーム。ブラウザで入力確認も可能。
  • ジオロケーション:ユーザの現在の位置の取得。
  • オフラインストレージ:インターネットに接続しなくてもウェブアプリケーションを使用可能。
  • Web Workers:JavaScript の計算が裏側で行われ、その計算が重たくてもブラウザが固まらない。

Q) よし、決心した!でもどうやって HTML5 を使えばよいでしょうか。

A) まずは注意点です。HTML5 はまだ作成中であるため、各ブラウザによって対応されている、または対応されていない機能があります。あるブラウザが対応するようになっても、対応しない古いブラウザもかなり多くあります。このため、対応しないブラウザでページを見た際、エラーメッセージが出ない、若しくは何も表示されない可能性があるといった点に気を付けないといけません。しかし、HTML5 は上位互換性を重要にしていますので、正しく利用すればそういう問題は少なくなるでしょう。

もう一つの注意点があります。未定な部分が少なくなって来たとはいえ、HTML5 は完成するまでに更に変わる可能性があります。一般的なウェブ開発者にとっては、最も簡単にできるのは既存の各ウェブページの最上部に HTML5 のドックタイプ(<!DOCTYPE HTML>)を挿入することです。そして、上記の W3C のオンライン確認ツールを利用すれば、有効な HTML5 になるまでに後何を変更すべきか分かります。それから、HTML5 を少しずつ追加すればウェブページの改善が楽になります。

Q) サンキュー。やってみます!困った時はどうすればいいですか。

A) HTML5 が人気になりつつあり、英語だけではなく日本語の資料も多くなって来ました。例えば: