WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

HTML によるプレゼン作成のススメ

昨日、 HTML5 勉強会で Opera の開発者向け機能についてプレゼンしてきました。会場が Opera の目黒オフィスということで急遽駆り出されました(笑)。

こういったプレゼンをするときに必要なのがプレゼン資料(スライド)の作成。これまでは Google Docs や OpenOffice.org で作っていたのですが、これがどうにも不便。ちょっとしたことを実現するにも複雑な操作が必要だったり、スライドに埋め込める素材にも制限があったりして、ずっと不満でした。

で、今回もそんなストレスを感じていて、ふと思ったのが、

HTML でスライド作ればいいじゃん!

ということ。

思い立ったが吉日で早速やってみたところ、これが意外にいける。画面サイズに合わせてスライドを拡大縮小する処理も CSS と僅かな JavaScript で難なく実現できて、専用のプレゼンソフトで作ったものと遜色ない資料が作れました(まあ、もともと私が作るプレゼンはすごく質素なのですが)。

そして、なんといっても HTML で表示できるものならなんでもスライドに埋め込めるのが素晴らしい。 JavaScript によるサンプル・デモなど、これまではいったんプレゼンを終了して見せていましたが、この方法ならそのまま表示できます。

そんなわけで、本日は HTML でプレゼン資料を作るのに使ったノウハウをご紹介します。 CSS によるコンテンツのレイアウト方法などはプレゼン資料以外にも応用できると思いますので、ぜひご覧ください。


ちなみに、このような試みは既に行われていて、有名な amachang 氏が S6 という凄いライブラリを公開されています。スライド遷移時のカッコいいトランジションが魅力的なのですが、私はそれぞれのスライドを個別の HTML にしたかったので利用を断念しました。 HTML が分かれていると、特定のスライドをすぐに表示・編集できるし、それぞれのページでまったく別のライブラリを読んだりもできて便利なんですよね。まあ、逆に不便な面もあって一長一短ですから、好みの問題ですね。

はてぶコメントで教えていただいたのですが、 Opera には Opera Show なんて機能があるようです。なんてこった orz

通常の Web ページとプレゼン用スライドの違い

スライドを HTML で作るとして、それは通常の Web ページとなにが違うのでしょうか。人によって求めるものは違うでしょうが、私はだいたい以下のようなことかなと思います。

  • スライドのアスペクト比(縦横比)は 4:3 に固定。
  • ページはスクロールさせない。
  • ブラウザのサイズに合わせてスライドの表示内容は拡大・縮小される。
  • スライド内の任意の位置にコンテンツを配置できる。
  • 簡単な操作でスライドを順番に再生できる。

以下では、これらを HTML で実現する方法を考えていきたいと思います。

なお、 IE のサポートはまったく考えていません。 IE8 なら背景以外は概ね問題なく表示されますが、 IE7 以前は崩れまくると思います(未確認)。あらかじめご了承ください。

スライドのアスペクト比を 4:3 に固定する

プレゼンはたいていプロジェクターに画面を映して行います。一般的にプロジェクターのアスペクト比は 4:3 なので、ブラウザのサイズに関わらず、スライドのアスペクト比も 4:3 に固定したいところです。これは CSS だけでは不可能なので(もし良い方法をご存知でしたら、ぜひ教えてください)、以下のような JavaScript (+jQuery) で調整します。

function layout() {
  var docEl  = document.documentElement;
  var width  = docEl.clientWidth;
  var height = docEl.clientHeight;
  var aspect = 4.0 / 3.0;
  if(width > height * aspect)
    width = height * aspect;
  else
    height = width / aspect;
  var css = {
    width: width + "px",
    height: height + "px",
    "font-size": height/20.0 + "px"
  };
  $(document.body).css(css);
}
$(window).resize(layout);
$(layout);

なにをやっているかは・・・まあ見たとおりです。ページ読み込み時とリサイズ時に、画面に収まる最大の 4:3 矩形を算出して、 BODY タグのスタイルシートに設定しています。ついでに、フォントサイズも画面の大きさに合わせて調整しています。

さらに、ブラウザの横幅が余るときはページを中央寄せして表示したいので、そのようにスタイルシートを設定します。

html {
  overflow:hidden;
  background-color: gray;
}
body {
  overflow:hidden;
  margin:0px auto;
  padding:0px;
  background-color:white;
}

こうすることで、 BODY が中央寄せされ、余った部分が灰色で表示されます。

背景の表示

背景は CSS の background-image を BODY に指定するだけで表示されます。ただし、それだけでは画面サイズの変更に追従しないので、 background-size も一緒に指定してやります。

body {
  background-image:url(background.png);
  background-size: 100%;
  -o-background-size: 100%;
  -webkit-background-size: 100%;
  -moz-background-size: 100%;
}

これで BODY 要素のサイズに合わせて背景画像も拡大縮小されます。 Firefox 3.5 は background-size に対応していませんが、近々正式版が出ると言われている 3.6 は対応しているようなので、特別な処理はせずに "-moz-" 付きの属性を指定してあります。したがって、記事末のサンプルも Firefox 3.5 では背景が正常に表示されません。ご了承ください。

コンテンツの配置

あとは、 BODY 内に普通にプレゼン内容を書いていけばスライドが完成します。ただ、欲を言えばデスクトップのプレゼン作成ツールのように、自由な場所にコンテンツを配置したいですよね。これは absolute ポジショニングで % による位置指定を行うことで実現できます。

まずは BODY 要素自身の position を relative に設定して、 BODY 直下の DIV 要素を absolute にします。

body {
  position:relative;
}
body>div {
  position:absolute;
}

そして、 DIV 要素の位置を % で指定すれば、画面サイズが変化しても自動的に追従してくれます。ほとんどのページの本文は以下のようにして表示しています。

<body>
  <div style="left:5%; right:5%; top:15%;">
    本文
  </div>
</body>

これで、好きな位置に DIV を配置してコンテンツを表示できます。

表示内容の記述

プレゼンに表示する内容は HTML で普通に記述できます。 JavaScript も IFRAME 使えるので、実際に動作する Web アプリケーションのライブデモをプレゼンの中に埋め込むことも可能です。技術プレゼンには最高の環境かと思います。

唯一の注意点は、すべてのサイズ指定を相対指定(% や em)で行わなければいけないということです。例えば、以下のような感じです。

h1 { font-size:150%; margin:0; padding:0; }
p { margin: 1em 0; }

また、画像を表示する際は、縦横どちらか一方のサイズのみを指定することで、画像のアスペクト比を保ったまま画面サイズの変更に追従させることが可能です。

<img src="images/dragonfly.png" style="width:80%;">

このようにすることで、ブラウザのサイズに関わらず同じレイアウトでスライドが表示されます。正直、やってみるまでは画面サイズによって多少は崩れるだろうと思っていたのですが、意外なことに綺麗に拡大・縮小してくれます。これには驚きました。最近のブラウザのレンダリングエンジンはとても優秀ですね。

ページ間のナビゲーション

スライドの表示はできたので、次はそれらを繋げて順番に表示する方法を考えます。当然、いろいろな方法があると思いますが、私は LINK タグを使って前後のページへのリンクを HTML に埋め込む方法をとりました。

<head>
  <!-- ... -->
  <link rel="prev" href="prev_slide.html">
  <link rel="next" href="next_slide.html">
  <!-- ... -->
</head>

これだとスライドの順番を変えるときに複数の HTML ファイルを書き換える必要があり、多少面倒なのですが、 HTML 的には非常に正しい方法です。実際、 Opera はこれを書くだけでマウスジェスチャーやナビゲーション・バーでスライド間を移動できます。実はこの方法を使った最大の理由も、まともなナビゲーションを用意する時間がなかったことでして、勉強会でプレゼンをしたときは本当にマウスジェスチャーでページ送りしていました。

他のブラウザでは Opera のようにはいかないので、マウスのクリックでページ送りすスクリプトを追加しました。

var point = null;

function onMouseDownPage(event) {
  var target = event.target;
  while(target) {
    if(target.nodeName.toUpperCase() == 'A') {
      point = null;
      return;
    }
    target = target.parentNode;
  }
  point = [event.pageX, event.pageY];
}

function onMouseUpPage(event) {
  if(point &&
     Math.abs(event.pageX - point[0]) < 2 &&
     Math.abs(event.pageY - point[1]) < 2) {
    var url = $("link[rel='next']").attr('href');
    if(url)
      window.location.assign(url);
  }
}

$(document).mousedown(onMouseDownPage);
$(document).mouseup(onMouseUpPage);

前のスライドに戻るときは、「戻る」ボタンでお願いします(^^;

サンプル

以上のような感じで、最終的にできたのがこのスライドです。前述のとおり Firefox 3.5 では背景が正しく表示されません。

以下の URL で、プレゼンだけを見ることができます。

http://webos-goodies.jp/attachments/presentation_u...

※ プレゼン中で使っている SVG 画像は、 dev.Opera から拝借してきました。現在 Opera しかサポートしていない機能を使っています。また、手抜きで SVG 画像だけは画面サイズの変更に追従していません。

実際にプレゼンを作ってみての感想は、「すごくイケてる!」です。テキストのスタイル調整も CSS で思いのままですし、手馴れたテキストエディタで書けるので作業効率も非常に高い。上のプレゼンでは、 google-code-prettify でソースの色分け表示もしています。なんでこれまでやらなかったのか、不思議で仕方ありません。これからはプレゼンを作るときは全部これでいこうw

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles