/** * jquery roundabout - v2.4.2 * http://fredhq.com/projects/roundabout * * moves list-items of enabled ordered and unordered lists long * a chosen path. includes the default "lazysusan" path, that * moves items long a spinning turntable. * * terms of use // jquery roundabout * * open source under the bsd license * * copyright (c) 2011-2012, fred leblanc * all rights reserved. * * redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * - neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * this software is provided by the copyright holders and contributors "as is" * and any express or implied warranties, including, but not limited to, the * implied warranties of merchantability and fitness for a particular purpose * are disclaimed. in no event shall the copyright holder or contributors be * liable for any direct, indirect, incidental, special, exemplary, or * consequential damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or business * interruption) however caused and on any theory of liability, whether in * contract, strict liability, or tort (including negligence or otherwise) * arising in any way out of the use of this software, even if advised of the * possibility of such damage. */ (function(a) { "use strict"; var b, c, d; a.extend({ roundaboutshapes: { def: "lazysusan", lazysusan: function(a, b, c) { return { x: math.sin(a + b), y: math.sin(a + 3 * math.pi / 2 + b) / 8 * c, z: (math.cos(a + b) + 1) / 2, scale: math.sin(a + math.pi / 2 + b) / 2 + .5 } } } }); b = { bearing: 0, tilt: 0, minz: 100, maxz: 280, minopacity: .4, maxopacity: 1, minscale: .4, maxscale: 1, duration: 600, btnnext: null, btnnextcallback: function() {}, btnprev: null, btnprevcallback: function() {}, btntoggleautoplay: null, btnstartautoplay: null, btnstopautoplay: null, easing: "swing", clicktofocus: true, clicktofocuscallback: function() {}, focusbearing: 0, shape: "lazysusan", debug: false, childselector: "li", startingchild: null, reflect: false, floatcomparisonthreshold: .001, autoplay: false, autoplayduration: 1e3, autoplaypauseonhover: false, autoplaycallback: function() {}, autoplayinitialdelay: 0, enabledrag: false, dropduration: 600, dropeasing: "swing", dropanimateto: "nearest", dropcallback: function() {}, dragaxis: "x", dragfactor: 4, triggerfocusevents: true, triggerblurevents: true, responsive: false }; c = { autoplayinterval: null, autoplayisrunning: false, autoplaystarttimeout: null, animating: false, childinfocus: -1, touchmovestartposition: null, stopanimation: false, lastanimationstep: false }; d = { init: function(e, f, g) { var h, i = (new date).gettime(); e = typeof e === "object" ? e : {}; f = a.isfunction(f) ? f : function() {}; f = a.isfunction(e) ? e : f; h = a.extend({}, b, e, c); return this.each(function() { var b = a(this), c = b.children(h.childselector).length, e = 360 / c, i = h.startingchild && h.startingchild > c - 1 ? c - 1 : h.startingchild, j = h.startingchild === null ? h.bearing : 360 - i * e, k = b.css("position") !== "static" ? b.css("position") : "relative"; b.css({ padding: 0, position: k }).addclass("roundabout-holder").data("roundabout", a.extend({}, h, { startingchild: i, bearing: j, oppositeoffocusbearing: d.normalize.apply(null, [h.focusbearing - 180]), dragbearing: j, period: e })); if (g) { b.unbind(".roundabout").children(h.childselector).unbind(".roundabout") } else { if (h.responsive) { a(window).bind("resize", function() { d.stopautoplay.apply(b); d.relayoutchildren.apply(b) }) } } if (h.clicktofocus) { b.children(h.childselector).each(function(c) { a(this).bind("click.roundabout", function() { var e = d.getplacement.apply(b, [c]); if (!d.isinfocus.apply(b, [e])) { d.stopanimation.apply(a(this)); if (!b.data("roundabout").animating) { d.animatebearingtofocus.apply(b, [e, b.data("roundabout").clicktofocuscallback]) } return false } }) }) } if (h.btnnext) { a(h.btnnext).bind("click.roundabout", function() { if (!b.data("roundabout").animating) { d.animatetonextchild.apply(b, [b.data("roundabout").btnnextcallback]) } return false }) } if (h.btnprev) { a(h.btnprev).bind("click.roundabout", function() { d.animatetopreviouschild.apply(b, [b.data("roundabout").btnprevcallback]); return false }) } if (h.btntoggleautoplay) { a(h.btntoggleautoplay).bind("click.roundabout", function() { d.toggleautoplay.apply(b); return false }) } if (h.btnstartautoplay) { a(h.btnstartautoplay).bind("click.roundabout", function() { d.startautoplay.apply(b); return false }) } if (h.btnstopautoplay) { a(h.btnstopautoplay).bind("click.roundabout", function() { d.stopautoplay.apply(b); return false }) } if (h.autoplaypauseonhover) { b.bind("mouseenter.roundabout.autoplay", function() { d.stopautoplay.apply(b, [true]) }).bind("mouseleave.roundabout.autoplay", function() { d.startautoplay.apply(b) }) } if (h.enabledrag) { if (!a.isfunction(b.drag)) { if (h.debug) { alert("you do not have the drag plugin loaded.") } } else if (!a.isfunction(b.drop)) { if (h.debug) { alert("you do not have the drop plugin loaded.") } } else { b.drag(function(a, c) { var e = b.data("roundabout"), f = e.dragaxis.tolowercase() === "x" ? "deltax" : "deltay"; d.stopanimation.apply(b); d.setbearing.apply(b, [e.dragbearing + c[f] / e.dragfactor]) }).drop(function(a) { var c = b.data("roundabout"), e = d.getanimatetomethod(c.dropanimateto); d.allowanimation.apply(b); d[e].apply(b, [c.dropduration, c.dropeasing, c.dropcallback]); c.dragbearing = c.period * d.getnearestchild.apply(b) }) } b.each(function() { var b = a(this).get(0), c = a(this).data("roundabout"), e = c.dragaxis.tolowercase() === "x" ? "pagex" : "pagey", f = d.getanimatetomethod(c.dropanimateto); if (b.addeventlistener) { b.addeventlistener("touchstart", function(a) { c.touchmovestartposition = a.touches[0][e] }, false); b.addeventlistener("touchmove", function(b) { var f = (b.touches[0][e] - c.touchmovestartposition) / c.dragfactor; b.preventdefault(); d.stopanimation.apply(a(this)); d.setbearing.apply(a(this), [c.dragbearing + f]) }, false); b.addeventlistener("touchend", function(b) { b.preventdefault(); d.allowanimation.apply(a(this)); f = d.getanimatetomethod(c.dropanimateto); d[f].apply(a(this), [c.dropduration, c.dropeasing, c.dropcallback]); c.dragbearing = c.period * d.getnearestchild.apply(a(this)) }, false) } }) } d.initchildren.apply(b, [f, g]) }) }, initchildren: function(b, c) { var e = a(this), f = e.data("roundabout"); b = b || function() {}; e.children(f.childselector).each(function(b) { var f, g, h, i = d.getplacement.apply(e, [b]); if (c && a(this).data("roundabout")) { f = a(this).data("roundabout").startwidth; g = a(this).data("roundabout").startheight; h = a(this).data("roundabout").startfontsize } a(this).addclass("roundabout-moveable-item").css("position", "absolute"); a(this).data("roundabout", { startwidth: f || a(this).width(), startheight: g || a(this).height(), startfontsize: h || parseint(a(this).css("font-size"), 10), degrees: i, backdegrees: d.normalize.apply(null, [i - 180]), childnumber: b, currentscale: 1, parent: e }) }); d.updatechildren.apply(e); if (f.autoplay) { f.autoplaystarttimeout = settimeout(function() { d.startautoplay.apply(e) }, f.autoplayinitialdelay) } e.trigger("ready"); b.apply(e); return e }, updatechildren: function() { return this.each(function() { var b = a(this), c = b.data("roundabout"), e = -1, f = { bearing: c.bearing, tilt: c.tilt, stage: { width: math.floor(a(this).width() * .9), height: math.floor(a(this).height() * .9) }, animating: c.animating, infocus: c.childinfocus, focusbearingradian: d.degtorad.apply(null, [c.focusbearing]), shape: a.roundaboutshapes[c.shape] || a.roundaboutshapes[a.roundaboutshapes.def] }; f.midstage = { width: f.stage.width / 2, height: f.stage.height / 2 }; f.nudge = { width: f.midstage.width + f.stage.width * .05, height: f.midstage.height + f.stage.height * .05 }; f.zvalues = { min: c.minz, max: c.maxz, diff: c.maxz - c.minz }; f.opacity = { min: c.minopacity, max: c.maxopacity, diff: c.maxopacity - c.minopacity }; f.scale = { min: c.minscale, max: c.maxscale, diff: c.maxscale - c.minscale }; b.children(c.childselector).each(function(g) { if (d.updatechild.apply(b, [a(this), f, g, function() { a(this).trigger("ready") }]) && (!f.animating || c.lastanimationstep)) { e = g; a(this).addclass("roundabout-in-focus") } else { a(this).removeclass("roundabout-in-focus") } }); if (e !== f.infocus) { if (c.triggerblurevents) { b.children(c.childselector).eq(f.infocus).trigger("blur") } c.childinfocus = e; if (c.triggerfocusevents && e !== -1) { b.children(c.childselector).eq(e).trigger("focus") } } b.trigger("childrenupdated") }) }, updatechild: function(b, c, e, f) { var g, h = this, i = a(b), j = i.data("roundabout"), k = [], l = d.degtorad.apply(null, [360 - j.degrees + c.bearing]); f = f || function() {}; l = d.normalizerad.apply(null, [l]); g = c.shape(l, c.focusbearingradian, c.tilt); g.scale = g.scale > 1 ? 1 : g.scale; g.adjustedscale = (c.scale.min + c.scale.diff * g.scale).tofixed(4); g.width = (g.adjustedscale * j.startwidth).tofixed(4); g.height = (g.adjustedscale * j.startheight).tofixed(4); i.css({ left: (g.x * c.midstage.width + c.nudge.width - g.width / 2).tofixed(0) + "px", top: (g.y * c.midstage.height + c.nudge.height - g.height / 2).tofixed(0) + "px", width: g.width + "px", height: g.height + "px", opacity: (c.opacity.min + c.opacity.diff * g.scale).tofixed(2), zindex: math.round(c.zvalues.min + c.zvalues.diff * g.z), fontsize: (g.adjustedscale * j.startfontsize).tofixed(1) + "px" }); j.currentscale = g.adjustedscale; if (h.data("roundabout").debug) { k.push('
'); k.push('child ' + e + "
"); k.push("left: " + i.css("left") + "
"); k.push("top: " + i.css("top") + "
"); k.push("width: " + i.css("width") + "
"); k.push("opacity: " + i.css("opacity") + "
"); k.push("height: " + i.css("height") + "
"); k.push("z-index: " + i.css("z-index") + "
"); k.push("font-size: " + i.css("font-size") + "
"); k.push("scale: " + i.data("roundabout").currentscale); k.push("
"); i.html(k.join("")) } i.trigger("reposition"); f.apply(h); return d.isinfocus.apply(h, [j.degrees]) }, setbearing: function(b, c) { c = c || function() {}; b = d.normalize.apply(null, [b]); this.each(function() { var c, e, f, g = a(this), h = g.data("roundabout"), i = h.bearing; h.bearing = b; g.trigger("bearingset"); d.updatechildren.apply(g); c = math.abs(i - b); if (!h.animating || c > 180) { return } c = math.abs(i - b); g.children(h.childselector).each(function(c) { var e; if (d.ischildbackdegreesbetween.apply(a(this), [b, i])) { e = i > b ? "clockwise" : "counterclockwise"; a(this).trigger("move" + e + "throughback") } }) }); c.apply(this); return this }, adjustbearing: function(b, c) { c = c || function() {}; if (b === 0) { return this } this.each(function() { d.setbearing.apply(a(this), [a(this).data("roundabout").bearing + b]) }); c.apply(this); return this }, settilt: function(b, c) { c = c || function() {}; this.each(function() { a(this).data("roundabout").tilt = b; d.updatechildren.apply(a(this)) }); c.apply(this); return this }, adjusttilt: function(b, c) { c = c || function() {}; this.each(function() { d.settilt.apply(a(this), [a(this).data("roundabout").tilt + b]) }); c.apply(this); return this }, animatetobearing: function(b, c, e, f, g) { var h = (new date).gettime(); g = g || function() {}; if (a.isfunction(f)) { g = f; f = null } else if (a.isfunction(e)) { g = e; e = null } else if (a.isfunction(c)) { g = c; c = null } this.each(function() { var i, j, k, l = a(this), m = l.data("roundabout"), n = !c ? m.duration : c, o = e ? e : m.easing || "swing"; if (!f) { f = { timerstart: h, start: m.bearing, totaltime: n } } i = h - f.timerstart; if (m.stopanimation) { d.allowanimation.apply(l); m.animating = false; return } if (i < n) { if (!m.animating) { l.trigger("animationstart") } m.animating = true; if (typeof a.easing.def === "string") { j = a.easing[o] || a.easing[a.easing.def]; k = j(null, i, f.start, b - f.start, f.totaltime) } else { k = a.easing[o](i / f.totaltime, i, f.start, b - f.start, f.totaltime) } if (d.compareversions.apply(null, [a().jquery, "1.7.2"]) >= 0 && !a.easing["easeoutback"]) { k = f.start + (b - f.start) * k } k = d.normalize.apply(null, [k]); m.dragbearing = k; d.setbearing.apply(l, [k, function() { settimeout(function() { d.animatetobearing.apply(l, [b, n, o, f, g]) }, 0) }]) } else { m.lastanimationstep = true; b = d.normalize.apply(null, [b]); d.setbearing.apply(l, [b, function() { l.trigger("animationend") }]); m.animating = false; m.lastanimationstep = false; m.dragbearing = b; g.apply(l) } }); return this }, animatetonearbychild: function(b, c) { var e = b[0], f = b[1], g = b[2] || function() {}; if (a.isfunction(f)) { g = f; f = null } else if (a.isfunction(e)) { g = e; e = null } return this.each(function() { var b, h, i = a(this), j = i.data("roundabout"), k = !j.reflect ? j.bearing % 360 : j.bearing, l = i.children(j.childselector).length; if (!j.animating) { if (j.reflect && c === "previous" || !j.reflect && c === "next") { k = math.abs(k) < j.floatcomparisonthreshold ? 360 : k; for (b = 0; b < l; b += 1) { h = { lower: j.period * b, upper: j.period * (b + 1) }; h.upper = b === l - 1 ? 360 : h.upper; if (k <= math.ceil(h.upper) && k >= math.floor(h.lower)) { if (l === 2 && k === 360) { d.animatetodelta.apply(i, [-180, e, f, g]) } else { d.animatebearingtofocus.apply(i, [h.lower, e, f, g]) } break } } } else { k = math.abs(k) < j.floatcomparisonthreshold || 360 - math.abs(k) < j.floatcomparisonthreshold ? 0 : k; for (b = l - 1; b >= 0; b -= 1) { h = { lower: j.period * b, upper: j.period * (b + 1) }; h.upper = b === l - 1 ? 360 : h.upper; if (k >= math.floor(h.lower) && k < math.ceil(h.upper)) { if (l === 2 && k === 360) { d.animatetodelta.apply(i, [180, e, f, g]) } else { d.animatebearingtofocus.apply(i, [h.upper, e, f, g]) } break } } } } }) }, animatetonearestchild: function(b, c, e) { e = e || function() {}; if (a.isfunction(c)) { e = c; c = null } else if (a.isfunction(b)) { e = b; b = null } return this.each(function() { var f = d.getnearestchild.apply(a(this)); d.animatetochild.apply(a(this), [f, b, c, e]) }) }, animatetochild: function(b, c, e, f) { f = f || function() {}; if (a.isfunction(e)) { f = e; e = null } else if (a.isfunction(c)) { f = c; c = null } return this.each(function() { var g, h = a(this), i = h.data("roundabout"); if (i.childinfocus !== b && !i.animating) { g = h.children(i.childselector).eq(b); d.animatebearingtofocus.apply(h, [g.data("roundabout").degrees, c, e, f]) } }) }, animatetonextchild: function(a, b, c) { return d.animatetonearbychild.apply(this, [arguments, "next"]) }, animatetopreviouschild: function(a, b, c) { return d.animatetonearbychild.apply(this, [arguments, "previous"]) }, animatetodelta: function(b, c, e, f) { f = f || function() {}; if (a.isfunction(e)) { f = e; e = null } else if (a.isfunction(c)) { f = c; c = null } return this.each(function() { var g = a(this).data("roundabout").bearing + b; d.animatetobearing.apply(a(this), [g, c, e, f]) }) }, animatebearingtofocus: function(b, c, e, f) { f = f || function() {}; if (a.isfunction(e)) { f = e; e = null } else if (a.isfunction(c)) { f = c; c = null } return this.each(function() { var g = a(this).data("roundabout").bearing - b; g = math.abs(360 - g) < math.abs(g) ? 360 - g : -g; g = g > 180 ? -(360 - g) : g; if (g !== 0) { d.animatetodelta.apply(a(this), [g, c, e, f]) } }) }, stopanimation: function() { return this.each(function() { a(this).data("roundabout").stopanimation = true }) }, allowanimation: function() { return this.each(function() { a(this).data("roundabout").stopanimation = false }) }, startautoplay: function(b) { return this.each(function() { var c = a(this), e = c.data("roundabout"); b = b || e.autoplaycallback || function() {}; clearinterval(e.autoplayinterval); e.autoplayinterval = setinterval(function() { d.animatetonextchild.apply(c, [b]) }, e.autoplayduration); e.autoplayisrunning = true; c.trigger("autoplaystart") }) }, stopautoplay: function(b) { return this.each(function() { clearinterval(a(this).data("roundabout").autoplayinterval); a(this).data("roundabout").autoplayinterval = null; a(this).data("roundabout").autoplayisrunning = false; if (!b) { a(this).unbind(".autoplay") } a(this).trigger("autoplaystop") }) }, toggleautoplay: function(b) { return this.each(function() { var c = a(this), e = c.data("roundabout"); b = b || e.autoplaycallback || function() {}; if (!d.isautoplaying.apply(a(this))) { d.startautoplay.apply(a(this), [b]) } else { d.stopautoplay.apply(a(this), [b]) } }) }, isautoplaying: function() { return this.data("roundabout").autoplayisrunning }, changeautoplayduration: function(b) { return this.each(function() { var c = a(this), e = c.data("roundabout"); e.autoplayduration = b; if (d.isautoplaying.apply(c)) { d.stopautoplay.apply(c); settimeout(function() { d.startautoplay.apply(c) }, 10) } }) }, normalize: function(a) { var b = a % 360; return b < 0 ? 360 + b : b }, normalizerad: function(a) { while (a < 0) { a += math.pi * 2 } while (a > math.pi * 2) { a -= math.pi * 2 } return a }, ischildbackdegreesbetween: function(b, c) { var d = a(this).data("roundabout").backdegrees; if (b > c) { return d >= c && d < b } else { return d < c && d >= b } }, getanimatetomethod: function(a) { a = a.tolowercase(); if (a === "next") { return "animatetonextchild" } else if (a === "previous") { return "animatetopreviouschild" } return "animatetonearestchild" }, relayoutchildren: function() { return this.each(function() { var b = a(this), c = a.extend({}, b.data("roundabout")); c.startingchild = b.data("roundabout").childinfocus; d.init.apply(b, [c, null, true]) }) }, getnearestchild: function() { var b = a(this), c = b.data("roundabout"), d = b.children(c.childselector).length; if (!c.reflect) { return (d - math.round(c.bearing / c.period) % d) % d } else { return math.round(c.bearing / c.period) % d } }, degtorad: function(a) { return d.normalize.apply(null, [a]) * math.pi / 180 }, getplacement: function(a) { var b = this.data("roundabout"); return !b.reflect ? 360 - b.period * a : b.period * a }, isinfocus: function(a) { var b, c = this, e = c.data("roundabout"), f = d.normalize.apply(null, [e.bearing]); a = d.normalize.apply(null, [a]); b = math.abs(f - a); return b <= e.floatcomparisonthreshold || b >= 360 - e.floatcomparisonthreshold }, getchildinfocus: function() { var b = a(this).data("roundabout"); return b.childinfocus > -1 ? b.childinfocus : false }, compareversions: function(a, b) { var c, d = a.split(/\./i), e = b.split(/\./i), f = d.length > e.length ? d.length : e.length; for (c = 0; c <= f; c++) { if (d[c] && !e[c] && parseint(d[c], 10) !== 0) { return 1 } else if (e[c] && !d[c] && parseint(e[c], 10) !== 0) { return -1 } else if (d[c] === e[c]) { continue } if (d[c] && e[c]) { if (parseint(d[c], 10) > parseint(e[c], 10)) { return 1 } else { return -1 } } } return 0 } }; a.fn.roundabout = function(b) { if (d[b]) { return d[b].apply(this, array.prototype.slice.call(arguments, 1)) } else if (typeof b === "object" || a.isfunction(b) || !b) { return d.init.apply(this, arguments) } else { a.error("method " + b + " does not exist for jquery.roundabout.") } } })(jquery)