123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- /*
- * 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.
- * - fixed the .spStop method where the 'last FPS' value was not being set, and the user specified FPS being ignore when .spStart was called.
- * 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');
- if ($._spritely.instances[el_id]['options']['fps']) {
- $._spritely.instances[el_id]['_last_fps'] = $._spritely.instances[el_id]['options']['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;
- if ($._spritely.instances[el_id]['type'] == 'sprite') {
- $(this).spSet('fps', fps);
- }
- $._spritely.instances[el_id]['_stopped'] = false;
- });
- 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) {}
|