以下是 jQuery图片滑动旋转切换特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery图片滑动旋转切换</title>
<link href="css/demos.css" rel="stylesheet" />
<style>
ul {
list-style: none;
padding: 0;
margin: 0 auto;
width: 42em;
height: 24em;
}
li {
height: 20em;
width: 30em;
background-color: #ccc;
text-align: center;
cursor: pointer;
}
li.roundabout-in-focus {
cursor: default;
}
li span {
display: block;
padding-top: 6em;
}
#carbonads-container .carbonad {
margin: 0 auto;
}
</style>
</head>
<body>
<h1></h1>
<ul>
<li><span>Block 1</span></li>
<li><span>Block 2</span></li>
<li><span>Block 3</span></li>
<li><span>Block 4</span></li>
<li><span>Block 5</span></li>
</ul>
<div class="interact">
</div>
<script src="js/jquery.js"></script>
<script src="js/jquery.roundabout2.js"></script>
<script>
$(document).ready(function() {
$('ul').roundabout();
});
</script>
</body>
</html>
JS代码(jquery.roundabout2.js):
/** * jQuery Roundabout - v2.1.1 * 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,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(){
}
,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,animating:false,childInFocus:-1,touchMoveStartPosition:null,stopAnimation:false,lastAnimationStep:false}
;
methods ={
// starters// -----------------------------------------------------------------------// init// starts up roundaboutinit: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 optionsvar 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 stylespadding:0,position:holderCSSPosition}
).addClass("roundabout-holder").data( // starting options"roundabout",$.extend({
}
,settings,{
startingChild:startingChild,bearing:startBearing,oppositeOfFocusBearing:methods.normalize.apply(null,[settings.focusBearing - 180]),dragBearing:startBearing,period:period}
));
// bind based on settings if this init call was not a relayoutif (!relayout){
// bind click-to-focusif (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 buttonsif (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 buttonsif (settings.btnPrev){
$(settings.btnPrev).bind("click.roundabout",function(){
methods.animateToPreviousChild.apply(self,[self.data("roundabout").btnPrevCallback]);
return false;
}
);
}
// bind toggle autoplay buttonsif (settings.btnToggleAutoplay){
$(settings.btnToggleAutoplay).bind("click.roundabout",function(){
methods.toggleAutoplay.apply(self);
return false;
}
);
}
// bind start autoplay buttonsif (settings.btnStartAutoplay){
$(settings.btnStartAutoplay).bind("click.roundabout",function(){
methods.startAutoplay.apply(self);
return false;
}
);
}
// bind stop autoplay buttonsif (settings.btnStopAutoplay){
$(settings.btnStopAutoplay).bind("click.roundabout",function(){
methods.stopAutoplay.apply(self);
return false;
}
);
}
// autoplay pause on hoverif (settings.autoplayPauseOnHover){
self.bind("mouseenter.roundabout.autoplay",function(){
methods.stopAutoplay.apply(self,[true]);
}
).bind("mouseleave.roundabout.autoplay",function(){
methods.startAutoplay.apply(self);
}
);
}
// drag and dropif (settings.enableDrag){
// on screenif (!$.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 mobileself.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 thisif (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);
}
}
);
}
// responsiveif (settings.responsive){
$(window).resize(function(){
methods.relayoutChildren.apply(self);
}
);
}
}
// start childrenmethods.initChildren.apply(self,[callback,relayout]);
}
);
}
,// initChildren// applys settings to child elements,starts roundaboutinitChildren: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 dataif (relayout){
startWidth = $(this).data("roundabout").startWidth;
startHeight = $(this).data("roundabout").startHeight;
startFontSize = $(this).data("roundabout").startFontSize;
}
// apply classes and css first$(this).addClass("roundabout-moveable-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 necessaryif (data.autoplay){
methods.startAutoplay.apply(self);
}
self.trigger('ready');
callback.apply(self);
return self;
}
,// positioning// -----------------------------------------------------------------------// updateChildren// move children elements into their proper locationsupdateChildren: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]}
;
// calculationsinfo.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 positionsself.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("roundabout-in-focus");
}
else{
$(this).removeClass("roundabout-in-focus");
}
}
);
if (inFocus !== info.inFocus){
// blur old childif (data.triggerBlurEvents){
self.children(data.childSelector).eq(info.inFocus).trigger("blur");
}
data.childInFocus = inFocus;
if (data.triggerFocusEvents && inFocus !== -1){
// focus new childself.children(data.childSelector).eq(inFocus).trigger("focus");
}
}
self.trigger("childrenUpdated");
}
);
}
,// updateChild// repositions a child element into its new positionupdateChild: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 * 2rad = methods.normalizeRad.apply(null,[rad]);
// get factors from shapefactors = info.shape(rad,info.focusBearingRadian,info.tilt);
// correctfactors.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 itemchild.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 purposesif (self.data("roundabout").debug){
out.push("<div style=\"font-weight:normal;
font-size:10px;
padding:2px;
width:" + child.css("width") + ";
background-color:#ffc;
\">");
out.push("<strong style=\"font-size:12px;
white-space:nowrap;
\">Child " + childPos + "</strong><br />");
out.push("<strong>left:</strong> " + child.css("left") + "<br />");
out.push("<strong>top:</strong> " + child.css("top") + "<br />");
out.push("<strong>width:</strong> " + child.css("width") + "<br />");
out.push("<strong>opacity:</strong> " + child.css("opacity") + "<br />");
out.push("<strong>height:</strong> " + child.css("height") + "<br />");
out.push("<strong>z-index:</strong> " + child.css("z-index") + "<br />");
out.push("<strong>font-size:</strong> " + child.css("font-size") + "<br />");
out.push("<strong>scale:</strong> " + child.data("roundabout").currentScale);
out.push("</div>");
child.html(out.join(""));
}
// trigger eventchild.trigger("reposition");
// callbackcallback.apply(self);
return methods.isInFocus.apply(self,[data.degrees]);
}
,// manipulation// -----------------------------------------------------------------------// setBearing// changes the bearing of the roundaboutsetBearing: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 bearingdata.bearing = bearing;
self.trigger("bearingSet");
methods.updateChildren.apply(self);
// not animating? we're done herediff = Math.abs(oldBearing - bearing);
if (!data.animating || diff > 180){
return;
}
// check to see if any of the children went through the backdiff = 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 givencallback.apply(this);
return this;
}
,// adjustBearing// change the bearing of the roundabout by a given degreeadjustBearing: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 roundaboutsetTilt:function(tilt,callback){
callback = callback || function(){
}
;
this.each(function(){
$(this).data("roundabout").tilt = tilt;
methods.updateChildren.apply($(this));
}
);
// call callback if one was givencallback.apply(this);
return this;
}
,// adjustTilt// changes the tilt of the roundaboutadjustTilt: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 hereanimateToBearing:function(bearing,duration,easing,passedData,callback){
var now = (new Date()).getTime();
callback = callback || function(){
}
;
// find callback function in argumentsif ($.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 timertimer = now - passedData.timerStart;
if (data.stopAnimation){
methods.allowAnimation.apply(self);
data.animating = false;
return;
}
// we need to animate moreif (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);
}
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 displayedmethods.animateToBearing.apply(self,[bearing,thisDuration,thisEasingType,passedData,callback]);
}
,0);
}
]);
// we're done animating}
else{
if (data.animating){
self.trigger("animationEnd");
}
data.lastAnimationStep = true;
bearing = methods.normalize.apply(null,[bearing]);
methods.setBearing.apply(self,[bearing]);
data.animating = false;
data.lastAnimationStep = false;
data.dragBearing = bearing;
callback.apply(self);
}
}
);
return this;
}
,// animateToNearbyChild// animates roundabout to a nearby childanimateToNearbyChild:function(passedArgs,which){
var duration = passedArgs[0],easing = passedArgs[1],callback = passedArgs[2] || function(){
}
;
// find callbackif ($.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 nextif ((data.reflect && which === "previous") || (!data.reflect && which === "next")){
// slightly adjust for rounding issuesbearing = (Math.abs(bearing) < data.floatComparisonThreshold) ? 360:bearing;
// clockwisefor (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 issuesbearing = (Math.abs(bearing) < data.floatComparisonThreshold || 360 - Math.abs(bearing) < data.floatComparisonThreshold) ? 0:bearing;
// counterclockwisefor (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 childanimateToNearestChild:function(duration,easing,callback){
callback = callback || function(){
}
;
// find callbackif ($.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 positionanimateToChild:function(childPosition,duration,easing,callback){
callback = callback || function(){
}
;
// find callbackif ($.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 childanimateToNextChild:function(duration,easing,callback){
return methods.animateToNearbyChild.apply(this,[arguments,"next"]);
}
,// animateToPreviousChild// animates roundabout to the preious childanimateToPreviousChild: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 callbackif ($.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 focusanimateBearingToFocus:function(degrees,duration,easing,callback){
callback = callback || function(){
}
;
// find callbackif ($.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 itstopAnimation:function(){
return this.each(function(){
$(this).data("roundabout").stopAnimation = true;
}
);
}
,// allowAnimation// clears the stop-animation hold placed by stopAnimationallowAnimation:function(){
return this.each(function(){
$(this).data("roundabout").stopAnimation = false;
}
);
}
,// autoplay// -----------------------------------------------------------------------// startAutoplay// starts autoplaying this roundaboutstartAutoplay: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 roundaboutstopAutoplay: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 autoplayif (!keepAutoplayBindings){
$(this).unbind(".autoplay")}
$(this).trigger("autoplayStop");
}
);
}
,// toggleAutoplay// toggles autoplay pause/resumetoggleAutoplay: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 autoplaychangeAutoplayDuration: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 < 360normalize:function(degrees){
var inRange = degrees % 360.0;
return (inRange < 0) ? 360 + inRange:inRange;
}
,// normalizeRad// regulates radians to be >= 0 and < Math.PI * 2normalizeRad: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 valuesisChildBackDegreesBetween: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 methodgetAnimateToMethod:function(effect){
effect = effect.toLowerCase();
if (effect === "next"){
return "animateToNextChild";
}
else if (effect === "previous"){
return "animateToPreviousChild";
}
// default selectionreturn "animateToNearestChild";
}
,// relayoutChildren// lays out children again with new contextual informationrelayoutChildren: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 bearinggetNearestChild: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 radiansdegToRad:function(degrees){
return methods.normalize.apply(null,[degrees]) * Math.PI / 180.0;
}
,// getPlacement// returns the starting degree for a given childgetPlacement: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 spectrumreturn (diff <= data.floatComparisonThreshold || diff >= 360 - data.floatComparisonThreshold);
}
}
;
// 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);
CSS代码(demos.css):
html{padding:0;margin:0;}
body{font-family:Palatino,Georgia,"Times New Roman",serif;padding:0;margin:0;font-size:1em;}
h1{font-size:4em;letter-spacing:-1px;margin:1em 0 0.5em;text-align:center;}
.interact{border-top:1px solid #ccc;margin-top:3em;margin-bottom:4em;padding-top:1.5em;text-align:center;}
.interact a{background-color:#2179b6;border-bottom:1px solid #084d7d;color:#eee;font-family:"Lucida Grande","Lucida Sans Unicode","Helvetica Neue",Arial,sans-serif;-webkit-border-radius:8px;-moz-border-radius:8px;-ms-border-radius:8px;-o-border-radius:8px;border-radius:8px;text-decoration:none;padding:8px 14px;margin:0 1em;}
.interact p{font-style:italic;color:#666;}
.return{font-size:1.5em;text-align:center;}
.return a{color:#2179b6;text-decoration:none;}
.return a:hover{text-decoration:underline;}