功能說明:
1.支援自動和手動兩種模式:自動模式下自動旋轉展示,手動模式下通過滑鼠選擇當前圖片,或通過提供的介面選擇上一張/下一張圖片。
2.可自行添加旋轉的緩動模式,預設模式為:勻速,先快後慢,先慢後快。
3.可自訂旋轉軌跡的寬和高。
4.支援IE6 7 8 9 10 firefox chrome等瀏覽器。
效果預覽:
實現原理:
根據對圖片在橢圓軌跡上的運動,動態改變縮放大小,實現立體的視覺效果。
程式碼分析:
複製代碼 代碼如下:
init:function(id,options){
var defaultOptions={
width:600, //容器寬
height:200, //容器高
imgWidth:100, //圖片寬
imgHeight:60, //圖片高
maxScale:1.5, //最大縮放倍數
minScale:0.5, //最小縮放倍數
rotateSpeed:10 //運轉速度
}
options=util.extend(defaultOptions,options);//參數設定
this.container=util.$(id);
this.width=options.width;
this.height=options.height;
imgWidth=this.imgWidth=options.imgWidth;
imgHeight=this.imgHeight=options.imgHeight;
this.maxScale=options.maxScale;
this.minScale=options.minScale;
scaleMargin=this.maxScale-this.minScale;
this.rotateSpeed=options.rotateSpeed;
this.imgs=util.$$('img',this.container);
this.setContainerSize(this.width,this.height);
initImgRC(this.imgs);
}
首先是初始化函數,裡面有defaultOptions作為預設值,使用者也可以傳入自訂的值,這些參數值包括:容器寬、容器高、圖片寬、圖片高、最大縮放倍數,最小縮放倍數,旋轉速度等。初始化之後,調用setContainerSize函數。
複製代碼 代碼如下:
/* 設定容器尺寸 */
setContainerSize:function(width,height){
width=width||this.width;
height=height||this.height;
this.container.style.position='relative';
this.container.style.width=width+'px';
this.container.style.height=height+'px';
changeRotateWH.call(this,width,height);//改變容器尺寸後改變旋轉軌跡
},
setContainerSize函數設定了容器的尺寸,容器尺寸的大小決定了旋轉軌跡的大小,例如當我們設定容器的高等於寬時,軌跡變成一個圓形。容器尺寸設定後,調用函數changeRotateWH。
複製代碼 代碼如下:
/* 改變橢圓旋轉軌跡的橫半軸長,豎半軸長*/
var changeRotateWH=function(width,height){
var halfScale=(this.maxScale-this.minScale)/2;//旋轉到中間位置時的圖片的縮放大小
rotate={};
rotate.originX=width/2;//旋轉原點X軸座標
rotate.originY=height/2;//旋轉原點Y軸座標
rotate.halfRotateWidth=(width-this.imgWidth)/2; //旋轉橫半軸長
rotate.halfRotateHeight=(height-this.imgHeight)/2; //旋轉豎半軸長
}
changeRotateWH函數的作用是根據容器的尺寸,設定橢圓旋轉軌跡的橫半軸長和豎半軸長(程式裡面的halfRotateWidth和halfRotateHeight,具體計算方法為:軌跡高=(容器高-圖片高)/2,軌跡寬=(容器寬-圖片寬)/2)),在高中數學中,我們學過橢圓的標準方程:(),這裡的橫半軸和豎半軸分別對應橢圓方程的a和b。由於這裡是橫軸較長的橢圓,所以a>b。
複製代碼 代碼如下:
/* 設定圖片旋轉角和初始位置,大小 */
var initImgRC=function(imgs){
var len=imgs.length;
con=(2*Math.PI)/len;
for(var i=0;i<len;i++){
imgs[i].RC=i*con;
imgs[i].style.width=imgWidth+'px';
imgs[i].style.height=imgHeight+'px';
setImgPositionAndSize(imgs[i],0);
}
}
設定好橢圓的基本座標系之後,我們可以根據圖片的數量,把圖片排列成一個橢圓的形狀,首先我們可以通過 2π/圖片數量 求得圖片之間間隔所佔的角度,然後把圖片平均分布在橢圓軌跡上,此時所有圖片就圍成了一個橢圓的形狀,到這裡圖片的初始分布狀態就出來了,接下來的任務就是需要使圖片沿著這個軌跡動起來。
複製代碼 代碼如下:
/* 設定圖片位置和大小的勻速變化 */
var setImgPositionAndSize=function(img,path,direction){
direction=direction||'CW';
var dir=direction=='CW'?-1:1;
img.RC+=(path*dir);
modifyImgAngle(img);
setImgSize(img);
}
該函數根據每張圖片位置的不同,設定圖片對應的尺寸,另外我們還需要傳入一個參數:direction(值為CW(順時針)或ACW(逆時針)),之後通過不斷增加圖片的RC屬性(旋轉角),使圖片勻速自動旋轉,這時自動旋轉的旋轉模式就ok了。
複製代碼 代碼如下:
/* 修改圖片旋轉角度(保證在0-2pai之間) */
var modifyImgAngle=function(img){
(img.RC>(2*Math.PI))&&(img.RC-=2*Math.PI);
(img.RC<0)&&(img.RC+=2*Math.PI);
}
在圖片旋轉之前,我們可以對每張圖片的角度做一個小小的修改,把旋轉角限定在0-2π之間,方便後續的計算。
複製代碼 代碼如下:
/* 設定圖片大小和位置 */
var setImgSize=function(img){
var left=rotate.originX+rotate.halfRotateWidth*Math.cos(img.RC)-imgWidth/2;
var top=rotate.originY-rotate.halfRotateHeight*Math.sin(img.RC)-imgHeight/2;
var scale=minScale+scaleMargin*(rotate.halfRotateHeight-rotate.halfRotateHeight*Math.sin(img.RC))/(2*rotate.halfRotateHeight);//圖片在該時刻的縮放比
img.style.cssText='position:absolute;left:'+left+'px;'
+'top:'+top+'px;'
+'width:'+imgWidth*scale+'px;'
+'height:'+imgHeight*scale+'px;'
+'z-index:'+Math.round(scale*100);
}
如何通過改變旋轉角使圖片按橢圓的軌跡旋轉呢?我們可以再回過頭看看之前的橢圓方程:(),由於需要處理的是旋轉,所以我們希望把對x,y的處理轉換成對旋轉角度的處理,因此x,y座標可以表示為:x=a*cosα , y=b*sinα 。圖片的X座標表示為:rotate.originX+rotate.halfRotateWidth*Math.cos(img.RC)-imgWidth/2(rotate.originX為原點X座標,這裡取容器的中心點),Y軸同理。之前說過圖片縮放大小的依據是圖片所處的位置,因此縮放比例scale的值則根據y座標所佔豎軸的長度進行計算。另外,層級關係z-index則根據scale的值進行計算,尺寸大得層級高,顯示在前面。
複製代碼 代碼如下:
/* 設定旋轉模式(自動/手動)*/
setPattern:function(patternName,option){
option=option||{};
this.pattern=patternName;
var rotateSpeed=option.rotateSpeed||10;
this.path=Math.PI/1000*rotateSpeed;
(typeof timeId!='undefined')&&window.clearInterval(timeId);
if(patternName==='auto'){//自動模式 可傳入旋轉方向:option.rotateDir 旋轉速度:option.rotateSpeed
var self=this;
var direction=option.rotateDir||'CW';//順時針:CW 逆時針:ACW
removeImgsHandler(this.imgs);
timeId=window.setInterval(function(){
for(var i=0,len=self.imgs.length;i<len;i++){
setImgPositionAndSize(self.imgs[i],self.path,direction);
}
},20);
}
else if(patternName==='hand'){//手動模式,可傳回呼函數:option.onSelected 緩動模式:option.tween
var onSelected=option.onSelected||util.emptyFunction;
var tween=Tween[tween]||Tween['easeOut'];//緩動模式預設為easeout
removeImgsHandler(this.imgs);
(typeof timeId!='undefined')&&window.clearInterval(timeId);
timeId=undefined;
bindHandlerForImgs(this.imgs,this.path,tween,onSelected);
}
}
}
現在看看使用者選擇手動模式或者自動模式的介面:setPattern方法,該方法根據傳入的字串不同而選擇不同的模式,“auto”為自動模式,該模式還可以傳入自訂參數,包括旋轉速度和旋轉方向。傳入“hand”則為手動模式,附加參數可以為手動選擇圖片後的回呼函數,以及旋轉的緩動模式。
複製代碼 代碼如下:
var Tween = {//緩動類 預設提供三種緩動模式:linear easein easeout
linear: function(t,b,c,d,dir){ return c*t/d*dir + b; },
easeIn: function(t,b,c,d,dir){
return c*(t/=d)*t*dir + b;
},
easeOut: function(t,b,c,d,dir){
return -c *(t/=d)*(t-2)*dir + b;
}
};
以上就是緩動模式類,預設的三個模式分別為:勻速 先慢後快 先快後慢。使用者可以調用addTweenFunction方法添加自己的緩動模式。