Hatena::ブログ(Diary)

latest log このページをアンテナに追加 RSSフィード

2010-12-17

クリスマスツリーを iPhone でも見れるようにしたよ


f:id:uupaa:20101219000618p:image

ジェバンニ仕事で、http://koebu.com/event/xmas/2010/iPhone / iPad に対応させました*1

目からビーム出して頑張ってる最中のツイートまとめ

iOS では、ユーザアクションを伴わない、audio.play() やaudio.load() は機能しない。さらにpreloadとautoplay属性も無効化されている http://bit.ly/fmLf5y in Device-Specific Considerations

http://twitter.com/uupaa/status/15433471463784449

なんかね、PCブラウザのように、audio.play() 呼んでも audio.load() 呼んでも動かなくて、色々ググッたんだよね。

iOS でBGMは、そのままでは自動再生できないので、ユーザに画面をタッチしてもらう必要がある

http://twitter.com/uupaa/status/15433728247468035

この時点では、window.addEventListener("touchstart", function() {...}, false) でイベントかすめとって、その隙に色々やったらどうなんだろう? とかモヤモヤしてた

つまりiOSでは、なんとしても画面にタッチしてもらって、そのタッチイベントハンドラ内で、audio.load()を含めゴニョゴニョまとめてやってしまって、ある程度までオーディオデータの読み込みが進んだら(canplayイベントが発生したら)、play()で再生すればできるのかな?

http://twitter.com/uupaa/status/15434696645156864

いやいやいやいやいや… ソレ無理あるだろうと。この後思い直すわけですが。

クリスマスツリーをiPhone対応にするためにゴリゴリ書き直してる。

http://twitter.com/uupaa/status/15439252250697728

寂しさと空腹に負けてツイート

iOSの<audio>とPCの<audio>は別ものなので、状態遷移そのものも別。

http://twitter.com/uupaa/status/15501925092958209

ドーパミンドバ〜 した時のつぶやき

そもそも状態遷移が違う

クリスマスツリーのページを、PCブラウザ向けに組んだ時は、

  1. mp3ファイルの一覧をAPIで取得する
  2. 取得したmp3ファイルを裏で読み込み、再生可能な状態になったらプレゼントとして登場させる
  3. クリックで再生開始

といった流れで、状態を管理していたのですが、

Apple の技術資料 http://bit.ly/fmLf5y にも書かれているとおり、ユーザアクションを伴わない形で audio.play() や audio.load() を実行しても iOS では機能しないから、PC用サイトのUIを組む感覚でiPhone用サイト組むと全くダメなことが判明。

モバイルSafariで動かすために、

  1. mp3ファイルの一覧をAPIで取得する
  2. プレゼントとして登場させる
  3. クリックでaudio.load()を実行 canplayイベントを待ってaudio.play()で再生開始

という別の流れを作成する必要がありました。

また、AudioPlayerクラスをPCブラウザ用(XmasPlayer)とは別に用意(XmasMobilePlayer)することで、モバイルSafariでの音声の再生も可能になりました。

# uupaa.js にはOOP的なクラスを作る機能があります。

モッサリをサクサクにする(アニメーションを軽くする)

クリスマスツリーのページのプレゼントボックスは、uupaa.js の uu.fx() を使いアニメーションをさせています。

uu.fx() の本質的なコードは以下のように、style.left と style.top といったスタイル属性を定期的に書き換えるというものです。

function tick() {
  node.style.left = x + "px";
  node.style.top  = y + "px";
}
setInteval(tick, 12);

ただ、left や top をタイマーで書き換える方式では、雪を4つ降らせただけでモッサリになってしまい、とても人前に出せる状態にはありませんでした。

そこで、前々からやりたかった機能(CSS3 Transition) を uu.fx() に組込み、機能強化を行いました*2

http://code.google.com/p/uupaa-js/source/detail?r=994

uu.fx.moveIn(), uu.fx.shlink(), uu.fx.flare(), uu.fx.puff() で、モバイルWebKitなら WebKitTransform を利用するように

uu.fx(node, duration, { tx, ty }) を指定時に、モバイルWebKitなら WebKitTransform を利用するように

従来は、

アニメーションを作成しますが、

これからは、

するだけで、uupaa.js が動作環境を判断し、PCブラウザなら tx → left と解釈、MobileSafari なら tx → WebKitTransform:transitionX と解釈するようになります。

つまり、

// これまで
uu.fx(node, duration, uu.env.mobile ? { transitionX:100, transitionY:100 } : { left:100, top:100 })

   ↓↓↓

// これから
uu.fx(node, duration, { tx:100, tx:100 })

スッキリ!

あっそうそう

IEモバイルSafariで見るとクリスマスツリーが短くて、その他のブラウザだと長かったり、複数の音声を同時に再生してガヤガヤできたりします。

あと、MobileSafariの<audio>は、ボリュームいじれないみたいなので、声が聞こえない時は iPod アプリを起動して音量大きくすると聞こえるようになります。

Boy Meets Girl !!

*1iOS4.2 以上推奨です。OSが古いと <audio> 動かないかも

*2:この辺は改めて別のエントリで説明します

2010-07-09

CSSセレクタを書き直したなど

2年ぶりにCSSセレクタを書き直しました

前回との違いは

  • 前作の精度を98点とすると今回は96点ぐらい。W3Cの意地悪テストを幾つかスキップ
  • コード量が半分に。実行速度はほぼ同じ
  • jQuery拡張, :active, :visited は非サポート(:visited は空の配列を返す)
  • W3Cの仕様に無い :contains(), E[ATTR != VALUE] は非サポート
    • MobileWebKitモードでは動作せず。フルビルドモードでは一応動作させてる
  • uu.query(expr) が返すNodeArrayはドキュメントオーダーでソート済みの状態に
  • 前回は2ヶ月かけて開発。今回は3日

メジャーライブラリとの速度比較

http://pigs.sourceforge.jp/blog/CSSSelector/CSSSelectorTestSuite/slickspeed/

query2(API OFF) が js製のCSSセレクタスコアで、query2(API ON) が querySelectorAll APIを利用した場合のスコアです。遅いブラウザ/古いブラウザで試すと分かりやすいかも。

ライブラリが読み込まれていないためにテストが途中で止まる事があります、そのような場合は(コントロールキーを押しながら)何度かリロードしてみてください(SlickSpeed のバグです)。SlickSpeed は iPhone だと動かないようです。

2010-06-29

uupaa2010-06-29

MultiTouch DnD + Gesture で Microsoft Surface 的な(2)

http://d.hatena.ne.jp/uupaa/20100625/1277424226 の続きです。

拡大/縮小/回転をクロスブラウザにしました。

http://jsdo.it/uupaa/MultiTouchDragAndGesture

iPhone(iOS4), IE 6+, Opera 10.50+, Firefox 3.5+, Google Chrome 5+, Safari 4+ で動作を確認しています。

2010-06-25

uupaa2010-06-25

MultiTouch DragAndDrop + Gesture で Microsoft Surface 的な

続き書きました http://d.hatena.ne.jp/uupaa/20100629

MultiTouch の習作として、Microsoft Surface ( youtube: http://bit.ly/1wTzk ) に似たインターフェースを js で実装してみました。

ピンチで拡大。回転。トリプルタップで元のサイズに戻ります。

jsdo.it では、コンテンツがiframeの中でロードされ実行されていますが、iframeの外側(jsdo.itの実行環境)で、各種環境(jQuery,jQuery UI,CSSjsなど)がロードされているためか、iPhoneでは二倍程度モッサリしてしまい本来のパフォーマンスが出せないようです。