Skip to content

Instantly share code, notes, and snippets.

@timmywil
Created May 28, 2011 20:13
Show Gist options
  • Select an option

  • Save timmywil/997191 to your computer and use it in GitHub Desktop.

Select an option

Save timmywil/997191 to your computer and use it in GitHub Desktop.
Oldschool Keyframes in jQuery
(function( $ ) {
$.fn.keyframe = function(){
if (arguments.length == 0) {
return this;
}
var self = this,
args = Array.prototype.slice.call( arguments ),
// List of keyframes
anim = args[0],
// Capture easing option
default_easing = args[1] || "linear",
// Stores object keys in numerical order
keys = [], key_len,
// Stores various animations to be executed
queue = [],
undefined,
k, n, l;
// Grab all the object key names
for ( k in anim ) {
keys.push(
// Allow use of 'start' instead of 0
(k == "start") ? 0 : parseInt( k )
);
}
// Sort the object's key names in numerical ascending order
keys.sort(function( a, b ) {
return ( a < b ) ? -1 : 1;
});
// Loop through all the keyframes, and build of queue of animations
for ( n = 0, l = keys.length; n < l; n++ ) {
(function( n ) {
var time = keys[ n ], // End-time
last_time = ( n > 0 ) ? keys[ n - 1 ] : 0, // Previous end-time
length = time - last_time, // Minimum duration of animation
batch, // Hold potential animations for this keyframe
prop,
prev, n, easing, value,
batch_name, a;
// If the time is 0 don't animate, just set it
if ( time === 0 ) {
self.stop( true, true ).css( anim["start"] );
// If this is the first non-zero keyframe, just queue up whatever
// is listed, instead of all the brouhaha below
} else if ( (n === 0) || (last_time === 0) ) {
queue.push({
start: 0,
end: time,
style: anim[ time ],
easing: default_easing
});
// Otherwise, go through each of this keyframe's properties, building
// up the necessary animation(s)
} else {
batch = {};
// Loop through keyframe's declared properties
for ( prop in anim[time] ) {
if( !anim[ time ].hasOwnProperty( prop ) ) {
continue;
}
prev = 0;
n = queue.length;
easing = default_easing;
value = anim[ time ][ prop ];
// If value is an array with easing, adjust stuff accordingly
if ( value.constructor.toString().match(/Array/) ) {
easing = value[ 1 ];
value = value[ 0 ];
}
// Find the last time this property was specified, default to 0
while ( n-- ) {
if ( !$.isFunction( queue[n] ) && queue[ n ][ "style" ][ prop ] != undefined ) {
prev = queue[ n ].end;
break;
}
}
// Combine animations with same time and easing, else make a new one
batch_name = prev + '-' + easing;
if ( batch[ batch_name ] === undefined ) {
batch[ batch_name ] = {
start: prev,
end: time,
style: {},
easing: easing
};
}
// Add in property
batch[ batch_name ][ "style" ][ prop ] = value;
}
// Add all animations from current batch in to queue
for ( a in batch ) {
queue.push( batch[a] );
}
}
})( n );
}
// Abuse jQuery.animate's magical queing properties
self.animate({ delay: 1 }, 0, function() {
// Loop through queue of animations, and invoke them all
// using jQuery's built-in `animate`, and `setTimeout`
for ( n = 0, l = queue.length; n < l; n++ ) {
(function( n ) {
var anim = queue[ n ];
self.animate({ delay: 1 }, { queue: false, duration: anim.start, complete: function() {
self.animate( anim.style, { duration: (anim.end - anim.start), easing: anim.easing, queue: false } );
}});
})( n );
}
self.animate( { delay: 1 }, queue[queue.length - 1].end );
});
return this;
};
})( jQuery );
// ============ Example ==============
// function r() { return Math.round( 50 * Math.random() ); }
// elem.keyframe({
// start: {
// top: 90 - r(), left: '-5%'
// },
// 8500: {
// top: 90 + r()
// },
// 16000: {
// top: 90 - r()
// },
// 24995: {
// top: 120 + r(), left: ['105%', 'linear']
// }
// }, 'easeInOutSine');
@hbarone
Copy link
Copy Markdown

hbarone commented Jun 14, 2011

I wrote this html code based on your example, but it did not work:

html:
div style="border-color:silver; border-style:solid; width:50px; height:50px; position:relative" id="box"
javascript:
$("#box").keyframe({
start: {
top: 90 , left: ['20', 'linear']
},
8500: {
top: 300, left: ['200', 'linear']
}
}, 'easeInOutSine');

@timmywil
Copy link
Copy Markdown
Author

I haven't released this really, but it works for me. Make sure you have the easing plugin as well if you're going to use an easing function.

@hbarone
Copy link
Copy Markdown

hbarone commented Jun 14, 2011

Yes, I have it
I wrote this simple html:
http://www.patrociniocoletivo.com.br/teste/jquery/quadro-chave-teste.html
thanks for help !!

@timmywil
Copy link
Copy Markdown
Author

timmywil commented Jun 14, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment