Created
December 8, 2011 14:23
-
-
Save ralphbean/1447119 to your computer and use it in GitHub Desktop.
Just a copy/paste of spritely.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* jQuery spritely 0.6.1 | |
* http://spritely.net/ | |
* | |
* Documentation: | |
* http://spritely.net/documentation/ | |
* | |
* Copyright 2010-2011, Peter Chater, Artlogic Media Ltd, http://www.artlogic.net/ | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* | |
* Change history: | |
* Version 0.6.1 | |
* - added some refinements from Gary hussey (http://bossninja.com/). Thanks Gary. | |
* spritely now correctly clears timeouts/intervals when destroying sprites. | |
* - added a goToFrame() method so you can set the current frame at any point. | |
* Version 0.6 | |
* - added events to the .sprite() method: on_first_frame, on_last_frame, on_frame: | |
* $('#sprite').sprite({ | |
* fps: 9, | |
* no_of_frames: 24, | |
* on_first_frame: function(obj) { | |
* obj.spState(1); // change to state 1 (first row) on frame 1 | |
* }, | |
* on_last_frame: function(obj) { | |
* obj.spStop(); // stop the animation on the last frame | |
* }, | |
* on_frame: { | |
* 8: function(obj) { | |
* obj.spState(2); // change to state 2 (row 2) on frame 8 | |
* }, | |
* 16: function(obj) { | |
* obj.spState(3); // change to state 3 (row 3) on frame 16 | |
* } | |
* } | |
* }); | |
* - added start_at_frame: $('#sprite').sprite({fps: 9, no_of_frames: 24, start_at_frame: 8}); | |
* Version 0.5 | |
* - added a 'destroy()' method which will stop the element's sprite behaviour, without actually removing the element. Example: $('#my_sprite').destroy() | |
* Version 0.4 | |
* - add up/down for 'pan' method. <ricky.hewitt@artlogic.net> | |
* - added 'dir' option for Sprites. This means a Sprite can be played in reverse. | |
* - removed alert message regarding jQuery.draggable (now uses console.log, if available) <ricky.hewitt@artlogic.net> | |
* Version 0.3b | |
* - added lockTo method for locking sprites to background images. $('#sprite').lockTo('#background, {'left': 380, 'top': -60, 'bg_img_width': 1110}); | |
* Version 0.2.1 | |
* - animate function will stop cycling after play_frames has completed | |
* Version 0.2 beta | |
* - added isDraggable method (requires jquery-ui) $('#sprite').sprite().isDraggable({start: null, stop: function() {alert('Ouch! You dropped me!')}); | |
* - sprites may be set to play a limited number of frames when instantiated, e.g. $('#sprite').sprite({fps: 9, no_of_frames: 3, play_frames: 30}) | |
* - sprite speed may be controlled at any point by setting the frames-per-second $('#sprite').fps(20); | |
* - sprites with multiple rows of frames may have there 'state' changed, e.g. to make the second row of frames | |
* active, use: $('#sprite').spState(2); - to return to the first row, use $('#sprite').spState(1); | |
* - background element speed may be controlled at any point with .spSpeed(), e.g. $('#bg1').spSpeed(10) | |
* - background elements may be set to a depth where 100 is the viewer (up close) and 0 is the horizon, e.g.: | |
* $('#bg1').pan({fps: 30, speed: 2, dir: 'left', depth: 30}); | |
* $('#bg2').pan({fps: 30, speed: 3, dir: 'left', depth: 70}); | |
* relative speed of backgrounds may now be set in a single action with $('#bg1, #bg2').spRelSpeed(20); | |
* which will make elements closer to the horizon (lower depths) move slower than closer elements (higher depths) | |
*/ | |
(function($) { | |
$._spritely = { | |
// shared methods and variables used by spritely plugin | |
animate: function(options) { | |
var el = $(options.el); | |
var el_id = el.attr('id'); | |
if (!$._spritely.instances[el_id]) { | |
return this; | |
} | |
options = $.extend(options, $._spritely.instances[el_id] || {}); | |
if (options.play_frames && !$._spritely.instances[el_id]['remaining_frames']) { | |
$._spritely.instances[el_id]['remaining_frames'] = options.play_frames + 1; | |
} | |
if (options.type == 'sprite' && options.fps) { | |
var frames; | |
var animate = function(el) { | |
var w = options.width, h = options.height; | |
if (!frames) { | |
frames = []; | |
total = 0 | |
for (var i = 0; i < options.no_of_frames; i ++) { | |
frames[frames.length] = (0 - total); | |
total += w; | |
} | |
} | |
if ($._spritely.instances[el_id]['current_frame'] == 0) { | |
if (options.on_first_frame) { | |
options.on_first_frame(el); | |
} | |
} else if ($._spritely.instances[el_id]['current_frame'] == frames.length - 1) { | |
if (options.on_last_frame) { | |
options.on_last_frame(el); | |
} | |
} | |
if (options.on_frame && options.on_frame[$._spritely.instances[el_id]['current_frame']]) { | |
options.on_frame[$._spritely.instances[el_id]['current_frame']](el); | |
} | |
if (options.rewind == true) { | |
if ($._spritely.instances[el_id]['current_frame'] <= 0) { | |
$._spritely.instances[el_id]['current_frame'] = frames.length - 1; | |
} else { | |
$._spritely.instances[el_id]['current_frame'] = $._spritely.instances[el_id]['current_frame'] - 1; | |
}; | |
} else { | |
if ($._spritely.instances[el_id]['current_frame'] >= frames.length - 1) { | |
$._spritely.instances[el_id]['current_frame'] = 0; | |
} else { | |
$._spritely.instances[el_id]['current_frame'] = $._spritely.instances[el_id]['current_frame'] + 1; | |
} | |
} | |
var yPos = $._spritely.getBgY(el); | |
el.css('background-position', frames[$._spritely.instances[el_id]['current_frame']] + 'px ' + yPos); | |
if (options.bounce && options.bounce[0] > 0 && options.bounce[1] > 0) { | |
var ud = options.bounce[0]; // up-down | |
var lr = options.bounce[1]; // left-right | |
var ms = options.bounce[2]; // milliseconds | |
el | |
.animate({top: '+=' + ud + 'px', left: '-=' + lr + 'px'}, ms) | |
.animate({top: '-=' + ud + 'px', left: '+=' + lr + 'px'}, ms); | |
} | |
} | |
if ($._spritely.instances[el_id]['remaining_frames'] && $._spritely.instances[el_id]['remaining_frames'] > 0) { | |
$._spritely.instances[el_id]['remaining_frames'] --; | |
if ($._spritely.instances[el_id]['remaining_frames'] == 0) { | |
$._spritely.instances[el_id]['remaining_frames'] = -1; | |
delete $._spritely.instances[el_id]['remaining_frames']; | |
return; | |
} else { | |
animate(el); | |
} | |
} else if ($._spritely.instances[el_id]['remaining_frames'] != -1) { | |
animate(el); | |
} | |
} else if (options.type == 'pan') { | |
if (!$._spritely.instances[el_id]['_stopped']) { | |
if (options.dir == 'up') { | |
$._spritely.instances[el_id]['l'] = $._spritely.getBgX(el).replace('px', ''); | |
$._spritely.instances[el_id]['t'] = ($._spritely.instances[el_id]['t'] - (options.speed || 1)) || 0; | |
} | |
else if (options.dir == 'down') { | |
$._spritely.instances[el_id]['l'] = $._spritely.getBgX(el).replace('px', ''); | |
$._spritely.instances[el_id]['t'] = ($._spritely.instances[el_id]['t'] + (options.speed || 1)) || 0; | |
} | |
else if (options.dir == 'left') { | |
$._spritely.instances[el_id]['l'] = ($._spritely.instances[el_id]['l'] - (options.speed || 1)) || 0; | |
$._spritely.instances[el_id]['t'] = $._spritely.getBgY(el).replace('px', ''); | |
} else { | |
$._spritely.instances[el_id]['l'] = ($._spritely.instances[el_id]['l'] + (options.speed || 1)) || 0; | |
$._spritely.instances[el_id]['t'] = $._spritely.getBgY(el).replace('px', ''); | |
} | |
// When assembling the background-position string, care must be taken | |
// to ensure correct formatting.. <ricky.hewitt@artlogic.net> | |
var bg_left = $._spritely.instances[el_id]['l'].toString(); | |
if (bg_left.indexOf('%') == -1) { | |
bg_left += 'px '; | |
} else { bg_left += ' '; } | |
var bg_top = $._spritely.instances[el_id]['t'].toString(); | |
if (bg_top.indexOf('%') == -1) { | |
bg_top += 'px '; | |
} else { bg_top += ' '; } | |
$(el).css('background-position', bg_left + bg_top); | |
} | |
} | |
$._spritely.instances[el_id]['options'] = options; | |
$._spritely.instances[el_id]['timeout'] = window.setTimeout(function() { | |
$._spritely.animate(options); | |
}, parseInt(1000 / options.fps)); | |
}, | |
randomIntBetween: function(lower, higher) { | |
return parseInt(rand_no = Math.floor((higher - (lower - 1)) * Math.random()) + lower); | |
}, | |
getBgY: function(el) { | |
if ($.browser.msie) { | |
// fixme - the background-position property does not work | |
// correctly in IE so we have to hack it here... Not ideal | |
// especially as $.browser is depricated | |
var bgY = $(el).css('background-position-y') || '0'; | |
} else { | |
var bgY = ($(el).css('background-position') || ' ').split(' ')[1]; | |
} | |
return bgY; | |
}, | |
getBgX: function(el) { | |
if ($.browser.msie) { | |
// see note, above | |
var bgX = $(el).css('background-position-x') || '0'; | |
} else { | |
var bgX = ($(el).css('background-position') || ' ').split(' ')[0]; | |
} | |
return bgX; | |
}, | |
get_rel_pos: function(pos, w) { | |
// return the position of an item relative to a background | |
// image of width given by w | |
var r = pos; | |
if (pos < 0) { | |
while (r < 0) { | |
r += w; | |
} | |
} else { | |
while (r > w) { | |
r -= w; | |
} | |
} | |
return r; | |
} | |
}; | |
$.fn.extend({ | |
spritely: function(options) { | |
var options = $.extend({ | |
type: 'sprite', | |
do_once: false, | |
width: null, | |
height: null, | |
fps: 12, | |
no_of_frames: 2, | |
stop_after: null | |
}, options || {}); | |
var el_id = $(this).attr('id'); | |
if (!$._spritely.instances) { | |
$._spritely.instances = {}; | |
} | |
if (!$._spritely.instances[el_id]) { | |
if (options.start_at_frame) { | |
$._spritely.instances[el_id] = {current_frame: options.start_at_frame - 1}; | |
} else { | |
$._spritely.instances[el_id] = {current_frame: -1}; | |
} | |
} | |
$._spritely.instances[el_id]['type'] = options.type; | |
$._spritely.instances[el_id]['depth'] = options.depth; | |
options.el = this; | |
options.width = options.width || $(this).width() || 100; | |
options.height = options.height || $(this).height() || 100; | |
var get_rate = function() { | |
return parseInt(1000 / options.fps); | |
} | |
if (!options.do_once) { | |
window.setTimeout(function() { | |
$._spritely.animate(options); | |
}, get_rate(options.fps)); | |
} else { | |
$._spritely.animate(options); | |
} | |
return this; // so we can chain events | |
}, | |
sprite: function(options) { | |
var options = $.extend({ | |
type: 'sprite', | |
bounce: [0, 0, 1000] // up-down, left-right, milliseconds | |
}, options || {}); | |
return $(this).spritely(options); | |
}, | |
pan: function(options) { | |
var options = $.extend({ | |
type: 'pan', | |
dir: 'left', | |
continuous: true, | |
speed: 1 // 1 pixel per frame | |
}, options || {}); | |
return $(this).spritely(options); | |
}, | |
flyToTap: function(options) { | |
var options = $.extend({ | |
el_to_move: null, | |
type: 'moveToTap', | |
ms: 1000, // milliseconds | |
do_once: true | |
}, options || {}); | |
if (options.el_to_move) { | |
$(options.el_to_move).active(); | |
} | |
if ($._spritely.activeSprite) { | |
if (window.Touch) { // iphone method see http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone/9 or http://www.nimblekit.com/tutorials.html for clues... | |
$(this)[0].ontouchstart = function(e) { | |
var el_to_move = $._spritely.activeSprite; | |
var touch = e.touches[0]; | |
var t = touch.pageY - (el_to_move.height() / 2); | |
var l = touch.pageX - (el_to_move.width() / 2); | |
el_to_move.animate({ | |
top: t + 'px', | |
left: l + 'px' | |
}, 1000); | |
}; | |
} else { | |
$(this).click(function(e) { | |
var el_to_move = $._spritely.activeSprite; | |
$(el_to_move).stop(true); | |
var w = el_to_move.width(); | |
var h = el_to_move.height(); | |
var l = e.pageX - (w / 2); | |
var t = e.pageY - (h / 2); | |
el_to_move.animate({ | |
top: t + 'px', | |
left: l + 'px' | |
}, 1000); | |
}); | |
} | |
} | |
return this; | |
}, | |
// isDraggable requires jQuery ui | |
isDraggable: function(options) { | |
if ((!$(this).draggable)) { | |
//console.log('To use the isDraggable method you need to load jquery-ui.js'); | |
return this; | |
} | |
var options = $.extend({ | |
type: 'isDraggable', | |
start: null, | |
stop: null, | |
drag: null | |
}, options || {}); | |
var el_id = $(this).attr('id'); | |
if (!$._spritely.instances[el_id]) { | |
return this; | |
} | |
$._spritely.instances[el_id].isDraggableOptions = options; | |
$(this).draggable({ | |
start: function() { | |
var el_id = $(this).attr('id'); | |
$._spritely.instances[el_id].stop_random = true; | |
$(this).stop(true); | |
if ($._spritely.instances[el_id].isDraggableOptions.start) { | |
$._spritely.instances[el_id].isDraggableOptions.start(this); | |
} | |
}, | |
drag: options.drag, | |
stop: function() { | |
var el_id = $(this).attr('id'); | |
$._spritely.instances[el_id].stop_random = false; | |
if ($._spritely.instances[el_id].isDraggableOptions.stop) { | |
$._spritely.instances[el_id].isDraggableOptions.stop(this); | |
} | |
} | |
}); | |
return this; | |
}, | |
active: function() { | |
// the active sprite | |
$._spritely.activeSprite = this; | |
return this; | |
}, | |
activeOnClick: function() { | |
// make this the active script if clicked... | |
var el = $(this); | |
if (window.Touch) { // iphone method see http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone/9 or http://www.nimblekit.com/tutorials.html for clues... | |
el[0].ontouchstart = function(e) { | |
$._spritely.activeSprite = el; | |
}; | |
} else { | |
el.click(function(e) { | |
$._spritely.activeSprite = el; | |
}); | |
} | |
return this; | |
}, | |
spRandom: function(options) { | |
var options = $.extend({ | |
top: 50, | |
left: 50, | |
right: 290, | |
bottom: 320, | |
speed: 4000, | |
pause: 0 | |
}, options || {}); | |
var el_id = $(this).attr('id'); | |
if (!$._spritely.instances[el_id]) { | |
return this; | |
} | |
if (!$._spritely.instances[el_id].stop_random) { | |
var r = $._spritely.randomIntBetween; | |
var t = r(options.top, options.bottom); | |
var l = r(options.left, options.right); | |
$('#' + el_id).animate({ | |
top: t + 'px', | |
left: l + 'px' | |
}, options.speed) | |
} | |
window.setTimeout(function() { | |
$('#' + el_id).spRandom(options); | |
}, options.speed + options.pause) | |
return this; | |
}, | |
makeAbsolute: function() { | |
// remove an element from its current position in the DOM and | |
// position it absolutely, appended to the body tag. | |
return this.each(function() { | |
var el = $(this); | |
var pos = el.position(); | |
el.css({position: "absolute", marginLeft: 0, marginTop: 0, top: pos.top, left: pos.left }) | |
.remove() | |
.appendTo("body"); | |
}); | |
}, | |
spSet: function(prop_name, prop_value) { | |
var el_id = $(this).attr('id'); | |
$._spritely.instances[el_id][prop_name] = prop_value; | |
return this; | |
}, | |
spGet: function(prop_name, prop_value) { | |
var el_id = $(this).attr('id'); | |
return $._spritely.instances[el_id][prop_name]; | |
}, | |
spStop: function(bool) { | |
$(this).each(function() { | |
var el_id = $(this).attr('id'); | |
$._spritely.instances[el_id]['_last_fps'] = $(this).spGet('fps'); | |
$._spritely.instances[el_id]['_stopped'] = true; | |
$._spritely.instances[el_id]['_stopped_f1'] = bool; | |
if ($._spritely.instances[el_id]['type'] == 'sprite') { | |
$(this).spSet('fps', 0); | |
} | |
if (bool) { | |
// set background image position to 0 | |
var bp_top = $._spritely.getBgY($(this)); | |
$(this).css('background-position', '0 ' + bp_top); | |
} | |
}); | |
return this; | |
}, | |
spStart: function() { | |
$(this).each(function() { | |
var el_id = $(this).attr('id'); | |
var fps = $._spritely.instances[el_id]['_last_fps'] || 12; | |
$._spritely.instances[el_id]['_stopped'] = false; | |
if ($._spritely.instances[el_id]['type'] == 'sprite') { | |
$(this).spSet('fps', fps); | |
} | |
}); | |
return this; | |
}, | |
spToggle: function() { | |
var el_id = $(this).attr('id'); | |
var stopped = $._spritely.instances[el_id]['_stopped'] || false; | |
var stopped_f1 = $._spritely.instances[el_id]['_stopped_f1'] || false; | |
if (stopped) { | |
$(this).spStart(); | |
} else { | |
$(this).spStop(stopped_f1); | |
} | |
return this; | |
}, | |
fps: function(fps) { | |
$(this).each(function() { | |
$(this).spSet('fps', fps); | |
}); | |
return this; | |
}, | |
goToFrame: function(n) { | |
var el_id = $(this).attr('id'); | |
if ($._spritely.instances && $._spritely.instances[el_id]) { | |
$._spritely.instances[el_id]['current_frame'] = n - 1; | |
} | |
return this; | |
}, | |
spSpeed: function(speed) { | |
$(this).each(function() { | |
$(this).spSet('speed', speed); | |
}); | |
return this; | |
}, | |
spRelSpeed: function(speed) { | |
$(this).each(function() { | |
var rel_depth = $(this).spGet('depth') / 100; | |
$(this).spSet('speed', speed * rel_depth); | |
}); | |
return this; | |
}, | |
spChangeDir: function(dir) { | |
$(this).each(function() { | |
$(this).spSet('dir', dir); | |
}); | |
return this; | |
}, | |
spState: function(n) { | |
$(this).each(function() { | |
// change state of a sprite, where state is the vertical | |
// position of the background image (e.g. frames row) | |
var yPos = ((n - 1) * $(this).height()) + 'px'; | |
var xPos = $._spritely.getBgX($(this)); | |
var bp = xPos + ' -' + yPos; | |
$(this).css('background-position', bp); | |
}); | |
return this; | |
}, | |
lockTo: function(el, options) { | |
$(this).each(function() { | |
var el_id = $(this).attr('id'); | |
if (!$._spritely.instances[el_id]) { | |
return this; | |
} | |
$._spritely.instances[el_id]['locked_el'] = $(this); | |
$._spritely.instances[el_id]['lock_to'] = $(el); | |
$._spritely.instances[el_id]['lock_to_options'] = options; | |
$._spritely.instances[el_id]['interval'] = window.setInterval(function() { | |
if ($._spritely.instances[el_id]['lock_to']) { | |
var locked_el = $._spritely.instances[el_id]['locked_el']; | |
var locked_to_el = $._spritely.instances[el_id]['lock_to']; | |
var locked_to_options = $._spritely.instances[el_id]['lock_to_options']; | |
var locked_to_el_w = locked_to_options.bg_img_width; | |
var locked_to_el_h = locked_to_el.height(); | |
var locked_to_el_y = $._spritely.getBgY(locked_to_el); | |
var locked_to_el_x = $._spritely.getBgX(locked_to_el); | |
var el_l = (parseInt(locked_to_el_x) + parseInt(locked_to_options['left'])); | |
var el_t = (parseInt(locked_to_el_y) + parseInt(locked_to_options['top'])); | |
el_l = $._spritely.get_rel_pos(el_l, locked_to_el_w); | |
$(locked_el).css({ | |
'top': el_t + 'px', | |
'left': el_l + 'px' | |
}); | |
} | |
}, options.interval || 20); | |
}); | |
return this; | |
}, | |
destroy: function() { | |
var el = $(this); | |
var el_id = $(this).attr('id'); | |
if ($._spritely.instances[el_id] && $._spritely.instances[el_id]['timeout']){ | |
window.clearInterval($._spritely.instances[el_id]['timeout']); | |
} | |
if ($._spritely.instances[el_id] && $._spritely.instances[el_id]['interval']) { | |
window.clearInterval($._spritely.instances[el_id]['interval']); | |
} | |
delete $._spritely.instances[el_id] | |
return this; | |
} | |
}) | |
})(jQuery); | |
// Stop IE6 re-loading background images continuously | |
try { | |
document.execCommand("BackgroundImageCache", false, true); | |
} catch(err) {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment