META-INF.resources.primefaces.ring.ring.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of primefaces Show documentation
Show all versions of primefaces Show documentation
PrimeFaces is one of the most popular UI libraries in Java EE Ecosystem and widely used by software companies, world renowned brands, banks, financial institutions, insurance companies, universities and more.
/**
* 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($) {
"use strict";
var defaults, internalData, methods;
// add default shape
$.extend({
roundaboutShapes: {
def: "lazySusan",
lazySusan: function (r, a, t) {
return {
x: Math.sin(r + a),
y: (Math.sin(r + 3 * Math.PI / 2 + a) / 8) * t,
z: (Math.cos(r + a) + 1) / 2,
scale: (Math.sin(r + Math.PI / 2 + a) / 2) + 0.5
};
}
}
});
defaults = {
bearing: 0.0,
tilt: 0.0,
minZ: 100,
maxZ: 280,
minOpacity: 0.4,
maxOpacity: 1.0,
minScale: 0.4,
maxScale: 1.0,
duration: 600,
btnNext: null,
btnNextCallback: function() {},
btnPrev: null,
btnPrevCallback: function() {},
btnToggleAutoplay: null,
btnStartAutoplay: null,
btnStopAutoplay: null,
easing: "swing",
clickToFocus: true,
clickToFocusCallback: function() {},
focusBearing: 0.0,
shape: "lazySusan",
debug: false,
childSelector: "li",
startingChild: null,
reflect: false,
floatComparisonThreshold: 0.001,
autoplay: false,
autoplayDuration: 1000,
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
};
internalData = {
autoplayInterval: null,
autoplayIsRunning: false,
autoplayStartTimeout: null,
animating: false,
childInFocus: -1,
touchMoveStartPosition: null,
stopAnimation: false,
lastAnimationStep: false
};
methods = {
// starters
// -----------------------------------------------------------------------
// init
// starts up roundabout
init: function(options, callback, relayout) {
var settings,
now = (new Date()).getTime();
options = (typeof options === "object") ? options : {};
callback = ($.isFunction(callback)) ? callback : function() {};
callback = ($.isFunction(options)) ? options : callback;
settings = $.extend({}, defaults, options, internalData);
return this
.each(function() {
// make options
var self = $(this),
childCount = self.children(settings.childSelector).length,
period = 360.0 / childCount,
startingChild = (settings.startingChild && settings.startingChild > (childCount - 1)) ? (childCount - 1) : settings.startingChild,
startBearing = (settings.startingChild === null) ? settings.bearing : 360 - (startingChild * period),
holderCSSPosition = (self.css("position") !== "static") ? self.css("position") : "relative";
self
.css({ // starting styles
padding: 0,
position: holderCSSPosition
})
.data( // starting options
"roundabout",
$.extend(
{},
settings,
{
startingChild: startingChild,
bearing: startBearing,
oppositeOfFocusBearing: methods.normalize.apply(null, [settings.focusBearing - 180]),
dragBearing: startBearing,
period: period
}
)
);
// unbind any events that we set if we're relaying out
if (relayout) {
self
.unbind(".roundabout")
.children(settings.childSelector)
.unbind(".roundabout");
} else {
// bind responsive action
if (settings.responsive) {
$(window).bind("resize", function() {
methods.stopAutoplay.apply(self);
methods.relayoutChildren.apply(self);
});
}
}
// bind click-to-focus
if (settings.clickToFocus) {
self
.children(settings.childSelector)
.each(function(i) {
$(this)
.bind("click.roundabout", function() {
var degrees = methods.getPlacement.apply(self, [i]);
if (!methods.isInFocus.apply(self, [degrees])) {
methods.stopAnimation.apply($(this));
if (!self.data("roundabout").animating) {
methods.animateBearingToFocus.apply(self, [degrees, self.data("roundabout").clickToFocusCallback]);
}
return false;
}
});
});
}
// bind next buttons
if (settings.btnNext) {
$(settings.btnNext)
.bind("click.roundabout", function() {
if (!self.data("roundabout").animating) {
methods.animateToNextChild.apply(self, [self.data("roundabout").btnNextCallback]);
}
return false;
});
}
// bind previous buttons
if (settings.btnPrev) {
$(settings.btnPrev)
.bind("click.roundabout", function() {
methods.animateToPreviousChild.apply(self, [self.data("roundabout").btnPrevCallback]);
return false;
});
}
// bind toggle autoplay buttons
if (settings.btnToggleAutoplay) {
$(settings.btnToggleAutoplay)
.bind("click.roundabout", function() {
methods.toggleAutoplay.apply(self);
return false;
});
}
// bind start autoplay buttons
if (settings.btnStartAutoplay) {
$(settings.btnStartAutoplay)
.bind("click.roundabout", function() {
methods.startAutoplay.apply(self);
return false;
});
}
// bind stop autoplay buttons
if (settings.btnStopAutoplay) {
$(settings.btnStopAutoplay)
.bind("click.roundabout", function() {
methods.stopAutoplay.apply(self);
return false;
});
}
// autoplay pause on hover
if (settings.autoplayPauseOnHover) {
self
.bind("mouseenter.roundabout.autoplay", function() {
methods.stopAutoplay.apply(self, [true]);
})
.bind("mouseleave.roundabout.autoplay", function() {
methods.startAutoplay.apply(self);
});
}
// drag and drop
if (settings.enableDrag) {
// on screen
if (!$.isFunction(self.drag)) {
if (settings.debug) {
alert("You do not have the drag plugin loaded.");
}
} else if (!$.isFunction(self.drop)) {
if (settings.debug) {
alert("You do not have the drop plugin loaded.");
}
} else {
self
.drag(function(e, properties) {
var data = self.data("roundabout"),
delta = (data.dragAxis.toLowerCase() === "x") ? "deltaX" : "deltaY";
methods.stopAnimation.apply(self);
methods.setBearing.apply(self, [data.dragBearing + properties[delta] / data.dragFactor]);
})
.drop(function(e) {
var data = self.data("roundabout"),
method = methods.getAnimateToMethod(data.dropAnimateTo);
methods.allowAnimation.apply(self);
methods[method].apply(self, [data.dropDuration, data.dropEasing, data.dropCallback]);
data.dragBearing = data.period * methods.getNearestChild.apply(self);
});
}
// on mobile
self
.each(function() {
var element = $(this).get(0),
data = $(this).data("roundabout"),
page = (data.dragAxis.toLowerCase() === "x") ? "pageX" : "pageY",
method = methods.getAnimateToMethod(data.dropAnimateTo);
// some versions of IE don't like this
if (element.addEventListener) {
element.addEventListener("touchstart", function(e) {
data.touchMoveStartPosition = e.touches[0][page];
}, false);
element.addEventListener("touchmove", function(e) {
var delta = (e.touches[0][page] - data.touchMoveStartPosition) / data.dragFactor;
e.preventDefault();
methods.stopAnimation.apply($(this));
methods.setBearing.apply($(this), [data.dragBearing + delta]);
}, false);
element.addEventListener("touchend", function(e) {
e.preventDefault();
methods.allowAnimation.apply($(this));
method = methods.getAnimateToMethod(data.dropAnimateTo);
methods[method].apply($(this), [data.dropDuration, data.dropEasing, data.dropCallback]);
data.dragBearing = data.period * methods.getNearestChild.apply($(this));
}, false);
}
});
}
// start children
methods.initChildren.apply(self, [callback, relayout]);
});
},
// initChildren
// applys settings to child elements, starts roundabout
initChildren: function(callback, relayout) {
var self = $(this),
data = self.data("roundabout");
callback = callback || function() {};
self.children(data.childSelector).each(function(i) {
var startWidth, startHeight, startFontSize,
degrees = methods.getPlacement.apply(self, [i]);
// on relayout, grab these values from current data
if (relayout && $(this).data("roundabout")) {
startWidth = $(this).data("roundabout").startWidth;
startHeight = $(this).data("roundabout").startHeight;
startFontSize = $(this).data("roundabout").startFontSize;
}
// apply classes and css first
$(this)
.addClass("ui-ring-item")
.css("position", "absolute");
// now measure
$(this)
.data(
"roundabout",
{
startWidth: startWidth || $(this).width(),
startHeight: startHeight || $(this).height(),
startFontSize: startFontSize || parseInt($(this).css("font-size"), 10),
degrees: degrees,
backDegrees: methods.normalize.apply(null, [degrees - 180]),
childNumber: i,
currentScale: 1,
parent: self
}
);
});
methods.updateChildren.apply(self);
// start autoplay if necessary
if (data.autoplay) {
data.autoplayStartTimeout = setTimeout(function() {
methods.startAutoplay.apply(self);
}, data.autoplayInitialDelay);
}
self.trigger('ready');
callback.apply(self);
return self;
},
// positioning
// -----------------------------------------------------------------------
// updateChildren
// move children elements into their proper locations
updateChildren: function() {
return this
.each(function() {
var self = $(this),
data = self.data("roundabout"),
inFocus = -1,
info = {
bearing: data.bearing,
tilt: data.tilt,
stage: {
width: Math.floor($(this).width() * 0.9),
height: Math.floor($(this).height() * 0.9)
},
animating: data.animating,
inFocus: data.childInFocus,
focusBearingRadian: methods.degToRad.apply(null, [data.focusBearing]),
shape: $.roundaboutShapes[data.shape] || $.roundaboutShapes[$.roundaboutShapes.def]
};
// calculations
info.midStage = {
width: info.stage.width / 2,
height: info.stage.height / 2
};
info.nudge = {
width: info.midStage.width + (info.stage.width * 0.05),
height: info.midStage.height + (info.stage.height * 0.05)
};
info.zValues = {
min: data.minZ,
max: data.maxZ,
diff: data.maxZ - data.minZ
};
info.opacity = {
min: data.minOpacity,
max: data.maxOpacity,
diff: data.maxOpacity - data.minOpacity
};
info.scale = {
min: data.minScale,
max: data.maxScale,
diff: data.maxScale - data.minScale
};
// update child positions
self.children(data.childSelector)
.each(function(i) {
if (methods.updateChild.apply(self, [$(this), info, i, function() { $(this).trigger('ready'); }]) && (!info.animating || data.lastAnimationStep)) {
inFocus = i;
$(this).addClass("ui-ring-item-focus");
} else {
$(this).removeClass("ui-ring-item-focus");
}
});
if (inFocus !== info.inFocus) {
// blur old child
if (data.triggerBlurEvents) {
self.children(data.childSelector)
.eq(info.inFocus)
.trigger("blur");
}
data.childInFocus = inFocus;
if (data.triggerFocusEvents && inFocus !== -1) {
// focus new child
self.children(data.childSelector)
.eq(inFocus)
.trigger("focus");
}
}
self.trigger("childrenUpdated");
});
},
// updateChild
// repositions a child element into its new position
updateChild: function(childElement, info, childPos, callback) {
var factors,
self = this,
child = $(childElement),
data = child.data("roundabout"),
out = [],
rad = methods.degToRad.apply(null, [(360.0 - data.degrees) + info.bearing]);
callback = callback || function() {};
// adjust radians to be between 0 and Math.PI * 2
rad = methods.normalizeRad.apply(null, [rad]);
// get factors from shape
factors = info.shape(rad, info.focusBearingRadian, info.tilt);
// correct
factors.scale = (factors.scale > 1) ? 1 : factors.scale;
factors.adjustedScale = (info.scale.min + (info.scale.diff * factors.scale)).toFixed(4);
factors.width = (factors.adjustedScale * data.startWidth).toFixed(4);
factors.height = (factors.adjustedScale * data.startHeight).toFixed(4);
// update item
child
.css({
left: ((factors.x * info.midStage.width + info.nudge.width) - factors.width / 2.0).toFixed(0) + "px",
top: ((factors.y * info.midStage.height + info.nudge.height) - factors.height / 2.0).toFixed(0) + "px",
width: factors.width + "px",
height: factors.height + "px",
opacity: (info.opacity.min + (info.opacity.diff * factors.scale)).toFixed(2),
zIndex: Math.round(info.zValues.min + (info.zValues.diff * factors.z)),
fontSize: (factors.adjustedScale * data.startFontSize).toFixed(1) + "px"
});
data.currentScale = factors.adjustedScale;
// for debugging purposes
if (self.data("roundabout").debug) {
out.push("");
out.push("Child " + childPos + "
");
out.push("left: " + child.css("left") + "
");
out.push("top: " + child.css("top") + "
");
out.push("width: " + child.css("width") + "
");
out.push("opacity: " + child.css("opacity") + "
");
out.push("height: " + child.css("height") + "
");
out.push("z-index: " + child.css("z-index") + "
");
out.push("font-size: " + child.css("font-size") + "
");
out.push("scale: " + child.data("roundabout").currentScale);
out.push("");
child.html(out.join(""));
}
// trigger event
child.trigger("reposition");
// callback
callback.apply(self);
return methods.isInFocus.apply(self, [data.degrees]);
},
// manipulation
// -----------------------------------------------------------------------
// setBearing
// changes the bearing of the roundabout
setBearing: function(bearing, callback) {
callback = callback || function() {};
bearing = methods.normalize.apply(null, [bearing]);
this
.each(function() {
var diff, lowerValue, higherValue,
self = $(this),
data = self.data("roundabout"),
oldBearing = data.bearing;
// set bearing
data.bearing = bearing;
self.trigger("bearingSet");
methods.updateChildren.apply(self);
// not animating? we're done here
diff = Math.abs(oldBearing - bearing);
if (!data.animating || diff > 180) {
return;
}
// check to see if any of the children went through the back
diff = Math.abs(oldBearing - bearing);
self.children(data.childSelector).each(function(i) {
var eventType;
if (methods.isChildBackDegreesBetween.apply($(this), [bearing, oldBearing])) {
eventType = (oldBearing > bearing) ? "Clockwise" : "Counterclockwise";
$(this).trigger("move" + eventType + "ThroughBack");
}
});
});
// call callback if one was given
callback.apply(this);
return this;
},
// adjustBearing
// change the bearing of the roundabout by a given degree
adjustBearing: function(delta, callback) {
callback = callback || function() {};
if (delta === 0) {
return this;
}
this
.each(function() {
methods.setBearing.apply($(this), [$(this).data("roundabout").bearing + delta]);
});
callback.apply(this);
return this;
},
// setTilt
// changes the tilt of the roundabout
setTilt: function(tilt, callback) {
callback = callback || function() {};
this
.each(function() {
$(this).data("roundabout").tilt = tilt;
methods.updateChildren.apply($(this));
});
// call callback if one was given
callback.apply(this);
return this;
},
// adjustTilt
// changes the tilt of the roundabout
adjustTilt: function(delta, callback) {
callback = callback || function() {};
this
.each(function() {
methods.setTilt.apply($(this), [$(this).data("roundabout").tilt + delta]);
});
callback.apply(this);
return this;
},
// animation
// -----------------------------------------------------------------------
// animateToBearing
// animates the roundabout to a given bearing, all animations come through here
animateToBearing: function(bearing, duration, easing, passedData, callback) {
var now = (new Date()).getTime();
callback = callback || function() {};
// find callback function in arguments
if ($.isFunction(passedData)) {
callback = passedData;
passedData = null;
} else if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
this
.each(function() {
var timer, easingFn, newBearing,
self = $(this),
data = self.data("roundabout"),
thisDuration = (!duration) ? data.duration : duration,
thisEasingType = (easing) ? easing : data.easing || "swing";
// is this your first time?
if (!passedData) {
passedData = {
timerStart: now,
start: data.bearing,
totalTime: thisDuration
};
}
// update the timer
timer = now - passedData.timerStart;
if (data.stopAnimation) {
methods.allowAnimation.apply(self);
data.animating = false;
return;
}
// we need to animate more
if (timer < thisDuration) {
if (!data.animating) {
self.trigger("animationStart");
}
data.animating = true;
if (typeof $.easing.def === "string") {
easingFn = $.easing[thisEasingType] || $.easing[$.easing.def];
newBearing = easingFn(null, timer, passedData.start, bearing - passedData.start, passedData.totalTime);
} else {
newBearing = $.easing[thisEasingType]((timer / passedData.totalTime), timer, passedData.start, bearing - passedData.start, passedData.totalTime);
}
// fixes issue #24, animation changed as of jQuery 1.7.2
// also addresses issue #29, using easing breaks "linear"
if (methods.compareVersions.apply(null, [$().jquery, "1.7.2"]) >= 0 && ($.easing["easeOutBack"])) {
newBearing = passedData.start + ((bearing - passedData.start) * newBearing);
}
newBearing = methods.normalize.apply(null, [newBearing]);
data.dragBearing = newBearing;
methods.setBearing.apply(self, [newBearing, function() {
setTimeout(function() { // done with a timeout so that each step is displayed
methods.animateToBearing.apply(self, [bearing, thisDuration, thisEasingType, passedData, callback]);
}, 0);
}]);
// we're done animating
} else {
data.lastAnimationStep = true;
bearing = methods.normalize.apply(null, [bearing]);
methods.setBearing.apply(self, [bearing, function() {
self.trigger("animationEnd");
}]);
data.animating = false;
data.lastAnimationStep = false;
data.dragBearing = bearing;
callback.apply(self);
}
});
return this;
},
// animateToNearbyChild
// animates roundabout to a nearby child
animateToNearbyChild: function(passedArgs, which) {
var duration = passedArgs[0],
easing = passedArgs[1],
callback = passedArgs[2] || function() {};
// find callback
if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
return this
.each(function() {
var j, range,
self = $(this),
data = self.data("roundabout"),
bearing = (!data.reflect) ? data.bearing % 360 : data.bearing,
length = self.children(data.childSelector).length;
if (!data.animating) {
// reflecting, not moving to previous || not reflecting, moving to next
if ((data.reflect && which === "previous") || (!data.reflect && which === "next")) {
// slightly adjust for rounding issues
bearing = (Math.abs(bearing) < data.floatComparisonThreshold) ? 360 : bearing;
// clockwise
for (j = 0; j < length; j += 1) {
range = {
lower: (data.period * j),
upper: (data.period * (j + 1))
};
range.upper = (j === length - 1) ? 360 : range.upper;
if (bearing <= Math.ceil(range.upper) && bearing >= Math.floor(range.lower)) {
if (length === 2 && bearing === 360) {
methods.animateToDelta.apply(self, [-180, duration, easing, callback]);
} else {
methods.animateBearingToFocus.apply(self, [range.lower, duration, easing, callback]);
}
break;
}
}
} else {
// slightly adjust for rounding issues
bearing = (Math.abs(bearing) < data.floatComparisonThreshold || 360 - Math.abs(bearing) < data.floatComparisonThreshold) ? 0 : bearing;
// counterclockwise
for (j = length - 1; j >= 0; j -= 1) {
range = {
lower: data.period * j,
upper: data.period * (j + 1)
};
range.upper = (j === length - 1) ? 360 : range.upper;
if (bearing >= Math.floor(range.lower) && bearing < Math.ceil(range.upper)) {
if (length === 2 && bearing === 360) {
methods.animateToDelta.apply(self, [180, duration, easing, callback]);
} else {
methods.animateBearingToFocus.apply(self, [range.upper, duration, easing, callback]);
}
break;
}
}
}
}
});
},
// animateToNearestChild
// animates roundabout to the nearest child
animateToNearestChild: function(duration, easing, callback) {
callback = callback || function() {};
// find callback
if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
return this
.each(function() {
var nearest = methods.getNearestChild.apply($(this));
methods.animateToChild.apply($(this), [nearest, duration, easing, callback]);
});
},
// animateToChild
// animates roundabout to a given child position
animateToChild: function(childPosition, duration, easing, callback) {
callback = callback || function() {};
// find callback
if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
return this
.each(function() {
var child,
self = $(this),
data = self.data("roundabout");
if (data.childInFocus !== childPosition && !data.animating) {
child = self.children(data.childSelector).eq(childPosition);
methods.animateBearingToFocus.apply(self, [child.data("roundabout").degrees, duration, easing, callback]);
}
});
},
// animateToNextChild
// animates roundabout to the next child
animateToNextChild: function(duration, easing, callback) {
return methods.animateToNearbyChild.apply(this, [arguments, "next"]);
},
// animateToPreviousChild
// animates roundabout to the preious child
animateToPreviousChild: function(duration, easing, callback) {
return methods.animateToNearbyChild.apply(this, [arguments, "previous"]);
},
// animateToDelta
// animates roundabout to a given delta (in degrees)
animateToDelta: function(degrees, duration, easing, callback) {
callback = callback || function() {};
// find callback
if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
return this
.each(function() {
var delta = $(this).data("roundabout").bearing + degrees;
methods.animateToBearing.apply($(this), [delta, duration, easing, callback]);
});
},
// animateBearingToFocus
// animates roundabout to bring a given angle into focus
animateBearingToFocus: function(degrees, duration, easing, callback) {
callback = callback || function() {};
// find callback
if ($.isFunction(easing)) {
callback = easing;
easing = null;
} else if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
return this
.each(function() {
var delta = $(this).data("roundabout").bearing - degrees;
delta = (Math.abs(360 - delta) < Math.abs(delta)) ? 360 - delta : -delta;
delta = (delta > 180) ? -(360 - delta) : delta;
if (delta !== 0) {
methods.animateToDelta.apply($(this), [delta, duration, easing, callback]);
}
});
},
// stopAnimation
// if an animation is currently in progress, stop it
stopAnimation: function() {
return this
.each(function() {
$(this).data("roundabout").stopAnimation = true;
});
},
// allowAnimation
// clears the stop-animation hold placed by stopAnimation
allowAnimation: function() {
return this
.each(function() {
$(this).data("roundabout").stopAnimation = false;
});
},
// autoplay
// -----------------------------------------------------------------------
// startAutoplay
// starts autoplaying this roundabout
startAutoplay: function(callback) {
return this
.each(function() {
var self = $(this),
data = self.data("roundabout");
callback = callback || data.autoplayCallback || function() {};
clearInterval(data.autoplayInterval);
data.autoplayInterval = setInterval(function() {
methods.animateToNextChild.apply(self, [callback]);
}, data.autoplayDuration);
data.autoplayIsRunning = true;
self.trigger("autoplayStart");
});
},
// stopAutoplay
// stops autoplaying this roundabout
stopAutoplay: function(keepAutoplayBindings) {
return this
.each(function() {
clearInterval($(this).data("roundabout").autoplayInterval);
$(this).data("roundabout").autoplayInterval = null;
$(this).data("roundabout").autoplayIsRunning = false;
// this will prevent autoplayPauseOnHover from restarting autoplay
if (!keepAutoplayBindings) {
$(this).unbind(".autoplay");
}
$(this).trigger("autoplayStop");
});
},
// toggleAutoplay
// toggles autoplay pause/resume
toggleAutoplay: function(callback) {
return this
.each(function() {
var self = $(this),
data = self.data("roundabout");
callback = callback || data.autoplayCallback || function() {};
if (!methods.isAutoplaying.apply($(this))) {
methods.startAutoplay.apply($(this), [callback]);
} else {
methods.stopAutoplay.apply($(this), [callback]);
}
});
},
// isAutoplaying
// is this roundabout currently autoplaying?
isAutoplaying: function() {
return (this.data("roundabout").autoplayIsRunning);
},
// changeAutoplayDuration
// stops the autoplay, changes the duration, restarts autoplay
changeAutoplayDuration: function(duration) {
return this
.each(function() {
var self = $(this),
data = self.data("roundabout");
data.autoplayDuration = duration;
if (methods.isAutoplaying.apply(self)) {
methods.stopAutoplay.apply(self);
setTimeout(function() {
methods.startAutoplay.apply(self);
}, 10);
}
});
},
// helpers
// -----------------------------------------------------------------------
// normalize
// regulates degrees to be >= 0.0 and < 360
normalize: function(degrees) {
var inRange = degrees % 360.0;
return (inRange < 0) ? 360 + inRange : inRange;
},
// normalizeRad
// regulates radians to be >= 0 and < Math.PI * 2
normalizeRad: function(radians) {
while (radians < 0) {
radians += (Math.PI * 2);
}
while (radians > (Math.PI * 2)) {
radians -= (Math.PI * 2);
}
return radians;
},
// isChildBackDegreesBetween
// checks that a given child's backDegrees is between two values
isChildBackDegreesBetween: function(value1, value2) {
var backDegrees = $(this).data("roundabout").backDegrees;
if (value1 > value2) {
return (backDegrees >= value2 && backDegrees < value1);
} else {
return (backDegrees < value2 && backDegrees >= value1);
}
},
// getAnimateToMethod
// takes a user-entered option and maps it to an animation method
getAnimateToMethod: function(effect) {
effect = effect.toLowerCase();
if (effect === "next") {
return "animateToNextChild";
} else if (effect === "previous") {
return "animateToPreviousChild";
}
// default selection
return "animateToNearestChild";
},
// relayoutChildren
// lays out children again with new contextual information
relayoutChildren: function() {
return this
.each(function() {
var self = $(this),
settings = $.extend({}, self.data("roundabout"));
settings.startingChild = self.data("roundabout").childInFocus;
methods.init.apply(self, [settings, null, true]);
});
},
// getNearestChild
// gets the nearest child from the current bearing
getNearestChild: function() {
var self = $(this),
data = self.data("roundabout"),
length = self.children(data.childSelector).length;
if (!data.reflect) {
return ((length) - (Math.round(data.bearing / data.period) % length)) % length;
} else {
return (Math.round(data.bearing / data.period) % length);
}
},
// degToRad
// converts degrees to radians
degToRad: function(degrees) {
return methods.normalize.apply(null, [degrees]) * Math.PI / 180.0;
},
// getPlacement
// returns the starting degree for a given child
getPlacement: function(child) {
var data = this.data("roundabout");
return (!data.reflect) ? 360.0 - (data.period * child) : data.period * child;
},
// isInFocus
// is this roundabout currently in focus?
isInFocus: function(degrees) {
var diff,
self = this,
data = self.data("roundabout"),
bearing = methods.normalize.apply(null, [data.bearing]);
degrees = methods.normalize.apply(null, [degrees]);
diff = Math.abs(bearing - degrees);
// this calculation gives a bit of room for javascript float rounding
// errors, it looks on both 0deg and 360deg ends of the spectrum
return (diff <= data.floatComparisonThreshold || diff >= 360 - data.floatComparisonThreshold);
},
// getChildInFocus
// returns the current child in focus, or false if none are in focus
getChildInFocus: function() {
var data = $(this).data("roundabout");
return (data.childInFocus > -1) ? data.childInFocus : false;
},
// compareVersions
// compares a given version string with another
compareVersions: function(baseVersion, compareVersion) {
var i,
base = baseVersion.split(/\./i),
compare = compareVersion.split(/\./i),
maxVersionSegmentLength = (base.length > compare.length) ? base.length : compare.length;
for (i = 0; i <= maxVersionSegmentLength; i++) {
if (base[i] && !compare[i] && parseInt(base[i], 10) !== 0) {
// base is higher
return 1;
} else if (compare[i] && !base[i] && parseInt(compare[i], 10) !== 0) {
// compare is higher
return -1;
} else if (base[i] === compare[i]) {
// these are the same, next
continue;
}
if (base[i] && compare[i]) {
if (parseInt(base[i], 10) > parseInt(compare[i], 10)) {
// base is higher
return 1;
} else {
// compare is higher
return -1;
}
}
}
// nothing was triggered, versions are the same
return 0;
}
};
// start the plugin
$.fn.roundabout = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === "object" || $.isFunction(method) || !method) {
return methods.init.apply(this, arguments);
} else {
$.error("Method " + method + " does not exist for jQuery.roundabout.");
}
};
})(jQuery);
/**
* PrimeFaces Ring Widget
*/
PrimeFaces.widget.Ring = PrimeFaces.widget.BaseWidget.extend({
init: function(cfg) {
this._super(cfg);
this.jq.roundabout(this.cfg);
}
});