enchant.jsでSpriteやLabelに対してjQueryを使ってエフェクトをかける方法についてはenchant.js + jQuery でエフェクトをつけるに書いた。使い慣れたjavascriptの機能を使ってエフェクトをかけられるのは魅力的だが、Spriteに対してCSS3の機能であるAnimationsを適用すると、iOS(iPhone,iPad等) の Mobile Safariで表示した際に、ピンボケというか過剰なアンチエイリアスというか、ぼやけた感じになってしまった。おかしいな、と思って実験したら、特定の条件下でAnimationsを適用した場合にぼやけてレンダリングされることが分かった。
特定の条件とは、
- div要素に対してCSSでbackground-imageを適用して画像を表示している(enchant.jsのEntity)
- 複数の画像にCSS3 Animationsを適用している
- どれかの要素でCSS3のアニメーションが継続中
といった場合だ。そこで、実験をしてみた。
※結論だけ知りたい人はこちらをクリック
実験
jQueryを使ってCSSを適用するため、jQueryと「enchant.js + jQuery でエフェクトをつける」で使ったenchant.prototype.jsは既に読み込み済みのものとする。
パターン1.拡大から縮小
以下のCSSとJavaScriptを用意して、test.pngが2倍から1倍に縮小されるプログラムを組んだ。
CSS
@-webkit-keyframes 'myanime' { 0% {-webkit-transform: scale(2.0); } 100% {-webkit-transform: scale(1.0); } }
javascript
var test = new Sprite(256,256); test.moveTo(320/2-256/2, 480/2-256/2); test.image = game.assets['test.png']; $(test.element()).css('-webkit-animation-name', 'myanime'); $(test.element()).css('-webkit-animation-duration', '1s'); $(test.element()).css('-webkit-animation-iteration-count', '1'); scene.addChild(test);
結果
パターン2.無限アニメする画像を1枚追加してみる
以下のCSSとJavaScriptを用意して、パターン1で表示した画像の下に、ずっと回転しつづける画像(-webkit-animation-iteration-countにinfiniteを指定したdiv要素)を表示してみる。
CSS
@-webkit-keyframes 'myanime' { 0% {-webkit-transform: scale(2.0); } 100% {-webkit-transform: scale(1.0); } } @-webkit-keyframes 'myrotation' { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } }
javascript
var foo = new Sprite(256,256); foo.moveTo(320/2-256/2, 480/2-256/2); foo.image = game.assets['test.png']; $(foo.element()).css('-webkit-animation-name', 'myrotation'); $(foo.element()).css('-webkit-animation-duration', '1s'); $(foo.element()).css('-webkit-animation-iteration-count', 'infinite'); scene.addChild(foo); var test = new Sprite(256,256); test.moveTo(320/2-256/2, 480/2-256/2); test.image = game.assets['test.png']; $(test.element()).css('-webkit-animation-name', 'myanime'); $(test.element()).css('-webkit-animation-duration', '1s'); $(test.element()).css('-webkit-animation-iteration-count', '1'); scene.addChild(test);
結果
解決編.
パターン2で手前に表示されていたSpriteのインスタンスtestを、jQueryによって生成されたimg要素に置き換える。
CSS
@-webkit-keyframes 'myanime' { 0% {-webkit-transform: scale(2.0); } 100% {-webkit-transform: scale(1.0); } } @-webkit-keyframes 'myrotation' { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } }
javascript
var foo = new Sprite(256,256); foo.moveTo(320/2-256/2, 480/2-256/2); foo.image = game.assets['test.png']; $(foo.element()).css('-webkit-animation-name', 'myrotation'); $(foo.element()).css('-webkit-animation-duration', '1s'); $(foo.element()).css('-webkit-animation-iteration-count', 'infinite'); scene.addChild(foo); var test = $("").attr({ src: './resources/test.png' }); test.css({ 'position': 'absolute', 'left': (320/2-256/2) + 'px', 'top': (480/2-256/2) + 'px', '-webkit-animation-name': 'myanime', '-webkit-animation-duration': '1s', '-webkit-animation-iteration-count': '1' }); $(scene.element()).append(test);
結果
結論としては、背景画像付きのdivにCSS3 Animationsを適用するのではなく、imgに対して適用すればよい。