FlashCS6+で生成したスプライトシートをjQueryでロードする実験(前編)
この記事は賞味期限切れです。(更新から1年が経過しています)
結構前の話ではありますが、FlashはCS6から、アニメーションを「スプライトシート」として書き出す機能が実装されています。 これはCreateJS等で簡単に再生出来る様になる便利な機能ですが、 今回はこのスプライトシートをjQueryで再生してみようというお話です。
スプライトシートってなに
スプライトシートは、CSSスプライトを利用したアニメーションテクニックです。 アニメーションの全フレームを一つの画像に並べて配置し、 要素の背景画像として埋め込んで background-position を変更していくことで パラパラ漫画のようなアニメーションを再生します。概要はこんな感じ。
一年程前、CS6が出るちょっとだけ前に似たような記事を書いたことがありました。
上の記事はまだCS6が出る前だったので自力でスプライトシートを作成する前提のものですが、 せっかく出力する機能があるんだから利用させて頂こうという事で、今回の記事なわけです。
CreateJSでやればよくない?
その通りです。その方が効率的なのでそれでいいと思います。
今回の記事は、あまり多くの依存ライブラリを読み込みたくなかったり、 宗教上の理由や遺言、あるいは政治的外圧等でjQueryで処理せざるを得ないケースを想定したものです。 CreateJSでの利用の仕方については、おそらく多くの方が詳しい記事を書いてくださっているので、そちらをご参照ください。
FlashCS6+でスプライトシートを生成する
例えば、FlashCS6でアニメーションのムービークリップ等を作り、それをステージに設置します。 その設置されたインスタンスを右クリックすると、コンテキストメニューに「スプライトシートを生成」が表れます。
それを選択すると現れるのがこんなダイアログ。
ここから「書き出し」を行うと、画像とデータ形式で指定したデータが出力されます。 指定出来るデータはJSON、各種ゲームエンジンの形式、そしてCreateJSのeaseljs形式です。
今回は使いやすそうだった “JSON-Array” 形式を使用します。
JSONデータの中身
“JSON-Array” で出力されたJSONデータの中身はこのような構成になっています。
{
"frames": [
{
"filename": "loading0000",
"frame": {"x":0,"y":0,"w":33,"h":33},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":33,"h":33},
"sourceSize": {"w":33,"h":33}
}
,{
"filename": "loading0001",
"frame": {"x":33,"y":0,"w":33,"h":33},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":33,"h":33},
"sourceSize": {"w":33,"h":33}
}
...
],
"meta": {
"app": "Adobe Flash CS6",
"version": "12.0.0.481",
"image": "sample.png",
"format": "RGBA8888",
"size": {"w":256,"h":256},
"scale": "1"
}
}
“frames” が実際のアニメーションのデータで、配列の中に個々のフレームの情報(サイズや座標等)を格納したオブジェクトが並んでいます。
“meta” にはスプライトシートの基本情報が格納されています。
このデータから再生するには…
アニメーションを再生するには、”frames”内のインデックスをひとつずつ進めてやり、格納されている座標情報を元に背景画像を移動してやる要領でしょうか。 座標は画像の左上からの座標なので、これを background-position に適用する際はマイナスの数値にしてやる必要がありますね。
再生させてみよう
では早速このデータを元にアニメーションを設置し、再生させてみましょう。 JSONデータも画像データもHTMLと同じディレクトリにある想定で進めます。
JSONを読み込む
まずJSONデータを読み込みます。
(function($){
$.getJSON("sample.json")
.then(function(data, status){
var my = {};
my.data = data;
// この中でいろいろしよう
});
}(jQuery));
アニメーションの要素を生成、配置する
受け取ったJSONのデータの内容から、アニメーション用のHTML要素を生成し、bodyに配置します。
my.node = $("<div>").css({
"width" : my.data.frames[0].sourceSize.w,
"height" : my.data.frames[0].sourceSize.h,
"background-image" : "url(" + my.data.meta.image + ")"
})
.appendTo($("body"));
要素のサイズははじめのフレームの “sourceSize” から取得することにします。
画像は、前述の通り同じディレクトリで展開する想定なのでそのまま代入していますが、
恐らく運用時は他のディレクトリに入れると思うので、その時はその時で画像へのパスをなんやかんやする必要がありますね。
再生する
今回は、単純に setTimeout で再生用の関数をぶん回して繰り返し再生を行います。
my.index = 0; // 現在のフレームインデックス
my.length = my.data.frames.length; // 合計フレーム数
my.interval = Math.floor(1000/30); // 約FPS30ぐらいで再生
my.play = function(){
var frame;
my.index = (my.index + 1) % (my.length - 1);
frame = my.data.frames[my.index].frame;
my.node.css(
"background-position",
"-" + frame.x + "px -" + frame.y + "px"
);
setTimeout(my.play, my.interval);
};
my.play();
他にも、ページのスクロール位置やマウスの挙動などをトリガーにしたりすると表現の幅が広がりますね。
全体のコード
(function($){
$.getJSON("sample.json")
.then(function(data, status){
var my = {};
my.data = data;
my.node = $("<div>").css({
"width" : my.data.frames[0].sourceSize.w,
"height" : my.data.frames[0].sourceSize.h,
"background-image" : "url(" + my.data.meta.image + ")"
})
.appendTo($("body"));
my.index = 0;
my.length = my.data.frames.length;
my.interval = Math.floor(1000/30);
my.play = function(){
var frame;
my.index = (my.index + 1) % (my.length - 1);
frame = my.data.frames[my.index].frame;
my.node.css(
"background-position",
"-" + frame.x + "px -" + frame.y + "px"
);
setTimeout(my.play, my.interval);
};
my.play();
});
}(jQuery));
めんどくさい!
勿論毎度これは面倒なので、ライブラリ化してみましたが、それは後編で。
コメント