Ruby

相変わらずJS+(なぜか)Flashの仕事がメインだけど、
合間を縫って今更ながらRuby勉強中。

全てがオブジェクトだったり演算子はメソッドだったり
徹底して美しく、かつ緩い言語なんだなというのが第1印象。

なによりJavascriptに近いものを感じるところが気に入った(笑)

IPA公式サイトに分かりやすい入門用教材があるのでおすすめ。
https://jinzaiipedia.ipa.go.jp/it_platform/education/oss

ハマったこと:AndroidにおけるCreateJS/Canvasのバグ

スマホアニメーション。
AndroidでもFlashが使えなくなって久しいが、
最近では手間のかかるCSS3アニメーションを諦めて、
多少再生パフォーマンスが悪くともFlashから直に出力できる
CreateJSによるアニメーションがソシャゲ界では定番のようだ。



特にAndroid4はCSSのマスクとアニメーションの併用が壊滅的なので、
マスクがちゃんと使えるというメリットも大きい。



さて、CreateJSで開発していると壁にぶち当たるのが
CreateJSというかCanvasのバグ。
しかもAndroidのWebViewだとさらに調子が悪くなる。
内容としては描画がおかしくなったり、ブラウザやアプリが落ちたり。



筆者の経験だとSamsung Galaxy SIIIやXperia Z、A等の
Snapdragon S4を搭載している機種で再現しやすい模様。
Canvasで本気でアニメーションさせるというネタがまだ少ないので
いつか同じ問題にぶつかる方のためにも解決策を記事に残して置く。



例えばcanvasのclearRect()において
キャンバスのサイズと同じ数値を指定すると落ちるなどが有名所だろうか。
CreateJSのclear()の実装はclearRect()なので当然落ちる。
ググると数回にピクセルを分けてclearRect()するなどの対処法が書かれているが、
これについては、easelJSの0.6.1以降では対策されているため、
そちらを使用すれば問題ない。
(まさか縦横ともに1ピクセル大きくクリアするだけで解決とは・・・)



それでも負荷のかかるアニメーションで落ちるパターンがあったので
調べたところ、



http://blog.happyelements.co.jp/2013/08/love-peace-and-android.html



こちらのブログに答えが見つかった。
そう、アニメーションを開始させる前、
stage = new createjs.Stage(canvas);
の後に
stage.clear();
を呼ぶことが大切だったようだ。
特に背景が透過しているアニメーションで発生しやすかったように思うが、
clear()で対策できるということは
明らかにCanvasメモリリークだろう。






Androidはひとつのカーネルでいろんな機種に対応できるのが売りであるが、
ドライバーはメーカーやチップベンダーがカスタムしたものを使用するため
ハードの性能は一流でもドライバーの完成度の低さに起因する
問題が多い気がする。
以前JSによるswfプレイヤーの開発を手伝っていたことがあったが、
とある機種ではJS内での簡単な少数演算で桁あふれを起こすこともあった。

OS自体は無料のはずなのに、めったなことがないとアップデートはされないし、
このままではiPhoneに負ける一方ではないか(もちろんiPhoneにもバグはあるが)。
個人的にはGoogleが好きなので、
Android陣営には4.4 Kitkatで是非とも頑張ってもらいたい所である。

雑感:バグに対する緊張感

ここ1年ほど、某SAPで働かせてもらっているが、
昨今の各ソシャゲメーカーの隆盛や衰退を肌身で感じて、ふと思ったこと。



不可能を可能にできたり自ら発案できるエンジニアは限りなく少ないけど、
発案者のアイデアを今ある環境で限りなく忠実に再現するのが真の技術屋なんじゃないか。



技術上がりの経営者はなかなかうまく行かないと言うし、
自分もそれで悩むことがあるけれど、
発案者のせっかくの発想を(バグのせいで)商業的にダメにすることだけは避けたい。



ゲーム業界で言うならば、重大なバグはどんなに素晴らしいゲームでも一瞬で屑にする。
ユーザーを平気でβテスターとして扱う昨今の風潮然り、
ネットワーク経由でのアップデートやクライアントサーバー型ゲームの台頭は
バグに対する提供者側の緊張感を著しく麻痺させている気がしてならない。



ユーザーも馬鹿じゃないし、任天堂のソフトのように流行り廃りを超えて
繁栄するためには面白さを遺憾なくユーザーに伝える土台が必要不可欠だと思う。



そこには扱える言語とか実務経験というレベルではなく、個々のエンジニアの思想から教育すべきである。
無駄に複雑なコードを書いたり、部下がついたから偉いと勘違いする割に、
発生してしまった障害への対応もろくにできず
責任も取らない(取れない)エンジニアは意外に多い。
こういう人間はSEどころかテスターにすらなるべきではない。



どんなにしっかり動作してもつまらないゲームは売れないだろうし、
ゲーム会社は確かに技術を売るところではないが、
ダメな技術屋によって会社がダメになることは往々にしてあるもの。



新しい技術を追いかけるのは非常に楽しいことであるが、
ユーザーは新技術だからと甘い目で見てはくれないし、それを開発者が期待してはならないと思う。

AndroidブラウザでCSS3する時の注意点など

前回からだいぶ間が空いたけど続きをば。



そういえば思っていたよりスマホでのHTML5開発の記事が増えない。
もはやそこまで最先端って感じでもなくなってきたし、
興味ある人が少ないのか、それとも情報を公開したくないのか。
半年ほど今の仕事をやってきて、
いろいろと慣れてきたので、

キーフレームアニメーションする時の注意点を
書きたいと思う。


まずキーフレーム定義において、
最初と最後の要素は0%またはfromおよび100%またはto
としてフレームを指定するのだが、
(以下は透明にフェードアウトする)

@-webkit-keyframes kf1 {
  from{
    opacity:1;
  }
  to{
    opacity:0;
  }
}

実はtoの部分にバグがあるため
これでは一部のバージョンでは動かない。
なのでそれを防ぐためには以下のように書く必要がある。

@-webkit-keyframes kf1 {
  from{
    opacity:1;
  }
  99.9%,to{
    opacity:0;
  }
}

toとともに99.9%の指定を追加した。
99.99%でももちろん構わないが、100%ではtoと同義なのでダメである。
これでは厳密にいうと時間軸が綺麗ではなくなるため
少々気持ちが悪いが、仕方がない。



もう一つ。
前半は透明度を変え、後半はtransformしたいといった場合、

@-webkit-keyframes kf1 {
  from{
    opacity:0;
  }
  50%{
    opacity:1;
    -webkit-transform:scale(1);
  }
  99.9%,to{
    -webkit-transform:scale(2);
  }
}

と書きたくなるがこれもダメである。
少々面倒だしキーフレームごとにどんな動きがあるのかわかりにくくなるが、

@-webkit-keyframes kf1 {
  from{
    opacity:0;
    -webkit-transform:scale(1);
  }
  50%{
    opacity:1;
    -webkit-transform:scale(1);
  }
  99.9%,to{
    opacity:1;
    -webkit-transform:scale(2);
  }
}

としなければならない。
また、transformはあくまでもひとつのプロパティなので、
その中で指定できる関数「translate()」や「scale()」を
組み合わせて使いたい場合、
どれかのキーフレームで指定したい関数がある場合は
上記のopacityとtranslateと同じように、
全てのキーフレームに記述しなければならない。



例えば、全体を通して2倍に拡大しながら移動して戻る場合

@-webkit-keyframes kf1 {
  from{
    -webkit-transform:translate(0px,0px) scale(1);
  }
  50%{
    -webkit-transform:translate(10px,10px);
  }
  99.9%,to{
    -webkit-transform:translate(0px,0px) scale(2);
  }
}

これでは期待通りに動かない。
面倒でも以下のようにする必要がある。

@-webkit-keyframes kf1 {
  from{
    -webkit-transform:translate(0px,0px) scale(1);
  }
  50%{
    -webkit-transform:translate(10px,10px) scale(1.5);
  }
  99.9%,to{
    -webkit-transform:translate(0px,0px) scale(2);
  }
}

つまり、最終的にscale(2)することは分かっていても、
50%の折り返し地点がキーフレームになっていれば
わざわざ計算してscale(1.5)を記述しなければならないのだ。

  • webkit-transformプロパティ内で

scale()を指定しない=scale(1)と同義になるためだ。
前述のopacityとの組み合わせの場合とは意味合いが異なるが、
実機でなかなか動かなくて「?」とならないためにも
律儀に綺麗に記述する習慣を身に着けよう。



誰かCSS3をグラフィカルに定義できるIDEを開発したら売れるんじゃなかろうか。
Android4.0についてはまだ研究段階だが、
既存のCSSはそのままでは動かないこともある模様。
把握できたらまた記事にしたいと思う。

楽しいこと:JS+CSS3アニメーション

久しぶりの更新です。
最近のお仕事はスマートフォン向けのブラウザソーシャルゲーム作成。
というか変換に近いかも。



スマホ対応サイトの開発に携わってる方は分かると思うけど、
iPhoneなどのiOSではFlashが動かない。
今やソーシャルゲームユーザーのスマホ率は40%を超えるそうで、
iPhoneに対応しないゲームなんて話にならないところまで来ているとか。



そこでFlashベースで作られたものを元に
HTML5(+JS+CSS3アニメーション)版に出すのが
現在の案件という訳。




今のところiOSAndroidがターゲットのため
Chromeで開発し、webkit系ブラウザ用で動くようにさえすれば
上記の両者に対応するということになるんだけど、
実際のところはそうもいかない。



自分自身去年末に3年愛用したW63CAからついに
AndroidケータイのXperia Acroに買い換えた訳だけど、
実は今回の仕事で初めて知ったことがある。
それはAndroidのブラウザはなんとChromeではないということ!



PCのChromeはベータの時から使っていたし、
SafariOS Xに搭載されたバージョン1から使っていて
どちらもwebkit系というのは知っていたけれど
さすがにAndroidのブラウザはChromeだろうと勝手に思い込んでいた。
調べてみる限りあのブラウザはあくまでも「ブラウザ」という名称だそうで、
確かに多くのソースを共有しているがChrome開発チームとは別の、
Androidチームが作っているそうだ。




そのためか実際、Webkit系ブラウザ向けのCSSアニメーションを使った
ブラウザアプリを開発していると
PC版SafariChromeとの多くの相違点にびっくりする。
PCではちゃんと表示できても、
実機で見るとまともに動かない部分がかなりある。
例えば-webkit-animation-fill-modeといったような、
webkitプリフィックスを使ったCSSのプロパティ等である。
上記は現在多くのAndroidケータイで採用されている
Android2.3のブラウザでは完全に無視される。



iPhoneのほうについては、3GSなどの古い機種でも
今のところ最新のiOSにバージョンアップすることによって
比較的最新のSafariが使えるためバグに悩まないで済むと思いきや、
何せアップデート自体に問題が多いため
(失敗すると最悪データ全消去なのは周りでは有名)
古いiOSのまま使っているユーザーも相当数いることから
iOS4でも検証を行わなければならないのは非常に面倒な話である。


こちらは動かないというよりは主にパフォーマンス面の
問題が多いので、画像の配置やJSの書き方などに一工夫必要になる。




今のところそれらについての情報が記載されているサイトが少ないので、
次回から少しずつここで書いていきたいと思う。

技術情報:困ったこと IEでAjax時に起こるエラー c00ce56e

お久しぶりでございます。




最近また懲りずにいろんなモノを
細々と作ってるわけだけど、
今回はサーバー側がPHPAjaxアプリ作成中に出くわしたこと。




Ajax開発者の方なら一度は目に触れたこともあろうかと思う
IEのエラー、
「エラー c00ce56e のため操作を完了できませんでした」
について。




そもそも社内で勝手に作ってるので
ページ文字コードは最初っからUTF-8
サーバーもFedoraUTF-8
PHPUTF-8とくればAjaxで困ることはないだろうと思っていたのだが・・・


サーバーからのレスポンスはJSON形式、
header('Content-type: application/json charset=utf-8');
とした後に
echo '"a" : "ほげほげ"'としたり
echo json_encode(Array("a" => "ほげほげ"))としたり(json_encodeは本当に便利!)
する際に、マルチバイト文字が含まれると上記のエラーが発生。
以前の案件で文字コード関連というのは予想がついていたのだが、
全部UTF-8なのにそりゃないだろ〜と調べていたら、判明。。




php.iniの
default_charset = "UTF8"
となっていた所を
default_charset = "UTF-8"
にしたら直ったorz
紛らわしいけどシフトJISSJISとかS-JISとかWindows31Jとかあるもんね。。
というわけで皆様もお気をつけくださいまし。

技術情報:困ったこと IFRAME内のhistoryへのアクセス

前回紹介したJSOSだが、
やはりクロスブラウザは面倒だなぁと思いながらもちまちま進行中。



とりあえず閉じるボタンと、リサイズ(右下のみ)は実装できてて、
あとはスキン対応なんかを意識してcssと分別化を計ったり。
相変わらずパクりですみません。イカす素材あれば教えてください。
FireFox3でも動くようになりました。
FFの場合、素早いリサイズを試みるとウィンドウが置いてかれるのは謎。



さて今日ぶつかった壁はiframe。
サンプルアプリ第一弾としてiframeによるブラウザもどきを
作ってる途中なんだけど、
今日の困ったちゃんはアドレスバーに必要不可欠な履歴ボタン!
つまり、戻るボタンと進むボタン。



普通に考えれば(window.)history.back()とhistory.forward()しかないので
当然[iframeエレメント.contentWindow.history]からアクセスするつもりだったのだが
当方のIE8だと「アクセスが拒否されました」とでる。
そういえば以前フルJSの案件やってたときも悩まされたような・・・
確かにクロスドメインと言えなくもないし、
まあ悪いことをしようと思えばできるだろうってのは想像つくんだけど、
FFなんかだと現状で動いてるし困った。
これだからセキュリティ云々って嫌い。例外処理と同じくらい嫌い。



とりあえずググると2000年ごろはそれで普通に動いてたらしい(笑)
IE8でも動くいい方法ないかな・・・