I have an implementation of Spritely running where the last half of the frames need to loop for infinity after the first play of all frames. Can this be done with a callback? - I looked at 'on_frame:' but this doesn't appear to run as a function.
The on_frame
is an object where you specify the frame on which to run a function. For example (excerpt from documentation, http://spritely.net/documentation/ ),
on_frame: { // note - on_frame is an object not a function
8: function(obj) { // called on frame 8
obj.spState(2); // change to state 2 (row 2) on frame 8
},
16: function(obj) { // called on frame 16
obj.spState(3); // change to state 3 (row 3) on frame 16
}
}
There is also the on_last_frame
which is a callback function. So what you can do is create two animations. The first may have all the frames and the second only half of them, the ones you need to loop forever. You can stop the first animation, by calling spStop()
on the sprite, from within the functions above and start the new spritely animation. Or simply specify that the first animation will run for a fixed number of animations by using the property play_frames
.
EDIT1 - example
This is a working example based on the sample code of spritely (http://spritely.net/downloads/spritely-0.6-sample-code.zip)
The first animation will run for 20 frames and then it will stop and the second animation, related to another element, will start.
html
<div id="container">
<div id="stage" class="stage">
<div id="tap" class="stage"></div>
<div id="bg" class="stage"></div>
<div id="clouds" class="stage"></div>
<div id="hill2" class="stage"></div>
<div id="hill1" class="stage"></div>
<div id="balloons" class="stage"></div>
<div id="logo">Spritely</div>
</div>
<div id="bird"></div>
<div id="bird2"></div>
</div>
js
$(document).ready(function () {
var anim1_frames = 20;
var current_frame = 0;
$('#bird').sprite({
fps: 9,
no_of_frames: 3,
on_last_frame: function (obj) {
current_frame += 3;
if (current_frame > anim1_frames) {
alert("First animation will stop. Second animation will start, of #bird2 element, which uses two frames and moves slowly. This could be a different sprite.");
obj.spStop();
$('#bird').hide();
$('#bird2').show().sprite({
fps: 1,
no_of_frames: 2,
start_at_frame: 2
});
}
}
});
$('#hill2').pan({
fps: 30,
speed: 2,
dir: 'left',
depth: 30
});
$('#hill1').pan({
fps: 30,
speed: 3,
dir: 'left',
depth: 70
});
});
css
#stage {
top: 0px;
left: 0px;
z-index: 100;
}
.stage {
position: absolute;
top: 0;
left: 0;
width: 100%;
min-width: 900px;
height: 359px;
overflow: hidden;
}
#bg {
background: #aedfe5 url(http://spritely.net/images/sky1.png) 0 0 repeat-x;
}
#clouds {
background: transparent url(http://spritely.net/images/cloud.png) 305px 102px repeat-x;
}
#hill2 {
background: transparent url(http://spritely.net/images/hill2.png) 0 258px repeat-x;
}
#hill1 {
background: transparent url(http://spritely.net/images/hill-with-windmill.png) 0 104px repeat-x;
}
#balloons {
position: relative;
left: 720px;
background: transparent url(http://spritely.net/images/balloons.png) 0 0 repeat-y;
}
#bird, #bird2 {
background: transparent url(http://spritely.net/images/bird-forward-back.png) 0 0 no-repeat;
position: absolute;
top: 150px;
left: 65px;
width: 180px;
height: 123px;
z-index: 2000;
cursor: pointer;
}
#bird2 {
display:none;
}
If it is required to use only one animation you may also use the function obj.goToFrame
within on_last_frame
but be careful with the logic.
EDIT2 - feedback on comments
I isolated the spritely part of your demo, removed all the css3 and modified it a bit in order to focus on how to make spritely work in your case.
js
$(document).ready(function () {
var anim1_frames_state1 = 75;
var anim1_frames_state2 = 47;
$('.anim').sprite({
fps: 40,
no_of_frames: anim1_frames_state1,
on_last_frame: function (obj) {
obj.spStop();
$('.anim').destroy();
$('.anim').hide();
$('.anim-old-2').show().sprite({
fps: 100,
no_of_frames: anim1_frames_state2
}).spState(2).fps(15);
}
});
});
html
<div class="anim"></div>
<div class="anim-old"></div>
<div class="anim-old-2"></div>
css
.anim {
background-size: 20850px 454px;
}
.anim, .anim-old, .anim-old-2 {
width: 278px;
height: 227px;
background: url("http://merlin.wecreatedigit.al/new-anim2.png") no-repeat;
display: block;
float: left;
position: relative;
}
.anim-old, .anim-old-2 {
display: none;
}
The image you are using has two rows. In spritely in order to use frames of another row the state
needs to be set via spState()
function. To make it work it is required to allow the first animation to use all frames of the first row/state and then switch to the second animation and make it use the frames of the second row/state. So this is like having two images, the first row and the second row, assign each to the two animations respectively and let the second animation run nonstop.