プロが教える店舗&オフィスのセキュリティ対策術

よろしくお願いいたします。

http://blog.rettuce.com/animation/animation-jpg/
こちらを参考に、jquery+png画像でgifアニメのようなアニメーションを作成しています。

サンプルの通りに作成すると問題なくアニメーションになっているのですが、
同じページ内に複数の異なるアニメーションを配置すると、うまく表示できず、おかしな動作になります。

javascriptは以下のように記述しています。

//アニメーション1
<script type="text/javascript">var id = "test1";
var width = 50;
var height = 50;
var fps = 10;
var src = "test1.png";
var frame = 0;
var max_frame = 10;
var onceFlg = false;
$(document).ready(
function (){
$("#"+id).css({
"background":"url("+src+")",
"width":width,
"height":height
});
var interval = 1/fps*1000;
animation = setInterval(intervalEvent, interval);
});
function intervalEvent(){
$("#"+id).css({
"background-position":"0 "+ -height * frame +"px"});
frame++;
if(frame>=max_frame){
if(onceFlg) clearInterval( animation );
frame = 0;
};
}
</script>

//アニメーション2
<script type="text/javascript">
var id2 = "test2";
var width = 500;
var height = 300;
var fps2 = 5;
var src2 = "test2.png";
var frame2 = 0;
var max_frame2 = 5;
var onceFlg2 = false;
$(document).ready(function (){
$("#"+id2).css({
"background":"url("+src2+")",
"width":width,
"height":height
});
var interval2 = 1/fps2*1000;
animation2 = setInterval(intervalEvent2, interval2);
});
function intervalEvent2(){
$("#"+id2).css({"background-position":"0 "+ -height * frame2 +"px"});
frame2++;
if(frame2>=max_frame2){
if(onceFlg2) clearInterval( animation2 );
frame2 = 0;
};
}
</script>


-------
それぞれ、一つずつ記述したときは、どちらも想い通りに動くのですが、
両方記述した際に、以下の2点のようになります。

1.アニメーション1が23×23個表示される
 ■ ←これをアニメーションだとすると、
■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■
    ・
    ・
    ・
という風に表示されます。

2.上記のjavascriptの記述のアニメーション1とアニメーション2の順序を入れ替えると、
 アニメーション1は正しく表示され、アニメーション2が表示されなくなります。。


それぞれ個別では動いているので、複数配置するときのjavascriptの書き方が間違っているのかと思うのですが、
原因をもしご存知でしたらお教えいただきたいと思い、質問させていただきました。

どうぞよろしくお願いいたします。

A 回答 (4件)

無駄なローカル変数を整理しました。



=====================
javascript
=====================
<script type="text/javascript">
$(function(){
/* 関数定義 */
var animeSprite = function ( $id, $fps, $src, $max, $flg ) {
var w = $($id).width();
var h = $($id).height();
var frame = 0;

$($id).css({
"width": w, "height": h,
"background-image": "url('"+$src+"')",
"background-repeat": "no-repeat"
});

var interval = (1/$fps)*1000;
var animation = setInterval(function () {
$($id).css({
"background-position": "0 " + (-h * frame) + "px"
});
frame++;
if(frame >= $max){
if($flg) clearInterval( animation );
frame = 0;
}
}, interval);
};

/* 実行 */
animeSprite( "#sprite1", 10, "./img/test1.png", 10, false );
animeSprite( ".sprite2", 5, "./img/test2.png", 5, false );

});
</script>
    • good
    • 0
この回答へのお礼

こちらも、ありがとうございます!
奇麗なソースを書くのって難しいですね。。
参考にさせていただきます。

お礼日時:2012/08/24 11:07

値が色々干渉しているんでしょうね。


同じような処理の重複は事故やメモリロスの元なので、ご提示いただいたサイトのスクリプトを関数化してみました。対象要素は、id、class両方に対応しています。
表示サイズはcssから取得しています。また、関数のオプションは以下の通りです。

animeSprite( "動かしたい対象要素", 秒何枚動かすのか, "画像のパス", 最大フレーム数, ループフラグ );

=====================
CSS
=====================
<style type="text/css">
#sprite1 { width:50px; height:50px; }
.sprite2 { width:500px; height:300px; }
</style>


=====================
javascript
=====================
<script type="text/javascript">
$(function(){
/* 関数定義 */
var animeSprite = function ( $id, $fps, $imgsrc, $max, $flg ){
var w = $($id).width();
var h = $($id).height();
var fps = $fps;
var src = $imgsrc;
var frame = 0;
var max_frame = $max;
var loopflg = $flg;

$($id).css({
"width": w, "height": h,
"background-image": "url('"+src+"')",
"background-repeat": "no-repeat"
});

var interval = (1/fps)*1000;
var animation = setInterval(function (){
$($id).css({
"background-position": "0 " + (-h * frame) + "px"
});
frame++;
if(frame >= max_frame){
if(loopflg) clearInterval( animation );
frame = 0;
}
}, interval);
};

/* 実行 */
animeSprite( "#sprite1", 10, "./img/test1.png", 10, false );
animeSprite( ".sprite2", 5, "./img/test2.png", 5, false );

});
</script>


=====================
HTML
=====================
<body>
<div id="wrapper">
<div id="sprite1"></div>
<div class="sprite2"></div>
<!--// #wrapper end //--></div>
</body>

参考URL:http://blog.rettuce.com/animation/animation-jpg/
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
お礼が遅くなり、申し訳ありません。

やはり書き方がいろいろややこしく書いてしまっていたのですね。
とても参考になりました!

お礼日時:2012/08/24 11:07

$(function(){


$('動かしたい対象').animate({"bgpos":フレーム数},{step:function(t){
$(this).css("background-position","0px -"+Math.floor(t).height())+"px");
})
})

自分で書いといてアレだけどこっちの方が効率良いですね
ってか最終的にこうしたんだった、忘れてた

ちなみにjqueryのプラグインでbackgroundPositionってのがあって
これいれとくとbackgroundPositionパラメータをアニメーションしたりとかすると
background-positionが動かせるようになります

スプライトアニメーションだけが目的なら正直上記ぐらいのコードなんで
別にプラグインまで入れる事ないかなとも思いますが

あ、jqueryの日本語サイトでstepの第一引数が0~1とかいってるけどあれ嘘ですよ
アニメーションするパラメータが一つの場合限定かもしれないけど
フレーム数に24とか入れれば0~24、結果の数値が入ってきます、
少なくともウチの環境ではいずれもそうでした
jqueryの計算の問題だから多分ブラウザによって違うってこともないと思います
    • good
    • 0
この回答へのお礼

こちらも、ありがとうございます。
とても参考になりました。

お礼日時:2012/08/24 11:05

animate()のstep使うといいよ、コードも少なくて済むし



stepには第一引数に結果の数値が入ってくるので
その数値を利用してスプライトにしてやればいい

$(function(){
$('動かしたい対象').animate({"bgpos":画像全体の高さ-ボックスの高さ},{step:function(t){
$(this).css("background-position","0px -"+(t-t%$(this).height())+"px");
})
})

そんなカンジ

参考URL:http://semooh.jp/jquery/api/effects/animate/para …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
お礼が遅くなり、申し訳ありません。

お礼日時:2012/08/24 11:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!