欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript橢圓旋轉(zhuǎn)相冊(cè)實(shí)現(xiàn)代碼

 更新時(shí)間:2012年01月16日 23:19:51   作者:  
支持自動(dòng)和手動(dòng)兩種模式:自動(dòng)模式下自動(dòng)旋轉(zhuǎn)展示,手動(dòng)模式下通過鼠標(biāo)選擇當(dāng)前圖片,或通過提供的接口選擇上一張/下一張圖片
功能說明:
1.支持自動(dòng)和手動(dòng)兩種模式:自動(dòng)模式下自動(dòng)旋轉(zhuǎn)展示,手動(dòng)模式下通過鼠標(biāo)選擇當(dāng)前圖片,或通過提供的接口選擇上一張/下一張圖片。
2.可自行添加旋轉(zhuǎn)的緩動(dòng)模式,默認(rèn)模式為:勻速,先快后慢,先慢后快。
3.可自定義旋轉(zhuǎn)軌跡的寬和高。
4.支持IE6 7 8 9 10 firefox chrome等瀏覽器。

效果預(yù)覽:

實(shí)現(xiàn)原理:
  根據(jù)對(duì)圖片在橢圓軌跡上的運(yùn)動(dòng),動(dòng)態(tài)改變縮放大小,實(shí)現(xiàn)立體的視覺效果。
代碼分析:
復(fù)制代碼 代碼如下:

init:function(id,options){
var defaultOptions={
width:600, //容器寬
height:200, //容器高
imgWidth:100, //圖片寬
imgHeight:60, //圖片高
maxScale:1.5, //最大縮放倍數(shù)
minScale:0.5, //最小縮放倍數(shù)
rotateSpeed:10 //運(yùn)轉(zhuǎn)速度
}
options=util.extend(defaultOptions,options);//參數(shù)設(shè)置
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);
}

  首先是初始化函數(shù),里面有defaultOptions作為默認(rèn)值,用戶也可以傳入自定義的值,這些參數(shù)值包括:容器寬、容器高、圖片寬、圖片高、最大縮放倍數(shù),最小縮放倍數(shù),旋轉(zhuǎn)速度等。初始化之后,調(diào)用setContainerSize函數(shù)。
復(fù)制代碼 代碼如下:

/* 設(shè)置容器尺寸 */
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);//改變?nèi)萜鞒叽绾蟾淖冃D(zhuǎn)軌跡
},

  setContainerSize函數(shù)設(shè)置了容器的尺寸,容器尺寸的大小決定了旋轉(zhuǎn)軌跡的大小,例如當(dāng)我們?cè)O(shè)置容器的高等于寬時(shí),軌跡變成一個(gè)圓形。容器尺寸設(shè)定后,調(diào)用函數(shù)changeRotateWH。
復(fù)制代碼 代碼如下:

/* 改變橢圓旋轉(zhuǎn)軌跡的橫半軸長,豎半軸長*/
var changeRotateWH=function(width,height){
var halfScale=(this.maxScale-this.minScale)/2;//旋轉(zhuǎn)到中間位置時(shí)的圖片的縮放大小
rotate={};
rotate.originX=width/2;//旋轉(zhuǎn)原點(diǎn)X軸坐標(biāo)
rotate.originY=height/2;//旋轉(zhuǎn)原點(diǎn)Y軸坐標(biāo)
rotate.halfRotateWidth=(width-this.imgWidth)/2; //旋轉(zhuǎn)橫半軸長
rotate.halfRotateHeight=(height-this.imgHeight)/2; //旋轉(zhuǎn)豎半軸長
}

  changeRotateWH函數(shù)的作用是根據(jù)容器的尺寸,設(shè)定橢圓旋轉(zhuǎn)軌跡的橫半軸長和豎半軸長(程序里面的halfRotateWidth和halfRotateHeight,具體計(jì)算方法為:軌跡高=(容器高-圖片高)/2,軌跡寬=(容器寬-圖片寬)/2)),在高中數(shù)學(xué)中,我們學(xué)過橢圓的標(biāo)準(zhǔn)方程:(),這里的橫半軸和豎半軸分別對(duì)應(yīng)橢圓方程的a和b。由于這里是橫軸較長的橢圓,所以a>b。
復(fù)制代碼 代碼如下:

/* 設(shè)置圖片旋轉(zhuǎn)角和初始位置,大小 */
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);
}
}

  設(shè)置好橢圓的基本坐標(biāo)系之后,我們可以根據(jù)圖片的數(shù)量,把圖片排列成一個(gè)橢圓的形狀,首先我們可以通過 2π/圖片數(shù)量 求得圖片之間間隔所占的角度,然后把圖片平均分布在橢圓軌跡上,此時(shí)所有圖片就圍成了一個(gè)橢圓的形狀,到這里圖片的初始分布狀態(tài)就出來了,接下來的任務(wù)就是需要使圖片沿著這個(gè)軌跡動(dòng)起來。
復(fù)制代碼 代碼如下:

/* 設(shè)置圖片位置和大小的勻速變化 */
var setImgPositionAndSize=function(img,path,direction){
direction=direction||'CW';
var dir=direction=='CW'?-1:1;
img.RC+=(path*dir);
modifyImgAngle(img);
setImgSize(img);
}

  該函數(shù)根據(jù)每張圖片位置的不同,設(shè)置圖片對(duì)應(yīng)的尺寸,另外我們還需要傳入一個(gè)參數(shù):direction(值為CW(順時(shí)針)或ACW(逆時(shí)針)),之后通過不斷增加圖片的RC屬性(旋轉(zhuǎn)角),使圖片勻速自動(dòng)旋轉(zhuǎn),這時(shí)自動(dòng)旋轉(zhuǎn)的旋轉(zhuǎn)模式就ok了。
復(fù)制代碼 代碼如下:

/* 修改圖片旋轉(zhuǎn)角度(保證在0-2pai之間) */
var modifyImgAngle=function(img){
(img.RC>(2*Math.PI))&&(img.RC-=2*Math.PI);
(img.RC<0)&&(img.RC+=2*Math.PI);
}

  在圖片旋轉(zhuǎn)之前,我們可以對(duì)每張圖片的角度做一個(gè)小小的修改,把旋轉(zhuǎn)角限定在0-2π之間,方便后續(xù)的計(jì)算。
 
復(fù)制代碼 代碼如下:

/* 設(shè)置圖片大小和位置 */
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);//圖片在該時(shí)刻的縮放比
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);
}

  如何通過改變旋轉(zhuǎn)角使圖片按橢圓的軌跡旋轉(zhuǎn)呢?我們可以再回過頭看看之前的橢圓方程:(),由于需要處理的是旋轉(zhuǎn),所以我們希望把對(duì)x,y的處理轉(zhuǎn)換成對(duì)旋轉(zhuǎn)角度的處理,因此x,y坐標(biāo)可以表示為:x=a*cosα , y=b*sinα 。圖片的X坐標(biāo)表示為:rotate.originX+rotate.halfRotateWidth*Math.cos(img.RC)-imgWidth/2(rotate.originX為原點(diǎn)X坐標(biāo),這里取容器的中心點(diǎn)),Y軸同理。之前說過圖片縮放大小的依據(jù)是圖片所處的位置,因此縮放比例scale的值則根據(jù)y坐標(biāo)所占豎軸的長度進(jìn)行計(jì)算。另外,層級(jí)關(guān)系z(mì)-index則根據(jù)scale的值進(jìn)行計(jì)算,尺寸大得層級(jí)高,顯示在前面。
復(fù)制代碼 代碼如下:

/* 設(shè)置旋轉(zhuǎn)模式(自動(dòng)/手動(dòng))*/
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'){//自動(dòng)模式 可傳入旋轉(zhuǎn)方向:option.rotateDir 旋轉(zhuǎn)速度:option.rotateSpeed
var self=this;
var direction=option.rotateDir||'CW';//順時(shí)針:CW 逆時(shí)針: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'){//手動(dòng)模式,可傳回調(diào)函數(shù):option.onSelected 緩動(dòng)模式:option.tween
var onSelected=option.onSelected||util.emptyFunction;
var tween=Tween[tween]||Tween['easeOut'];//緩動(dòng)模式默認(rèn)為easeout
removeImgsHandler(this.imgs);
(typeof timeId!='undefined')&&window.clearInterval(timeId);
timeId=undefined;
bindHandlerForImgs(this.imgs,this.path,tween,onSelected);
}
}
}

  現(xiàn)在看看用戶選擇手動(dòng)模式或者自動(dòng)模式的接口:setPattern方法,該方法根據(jù)傳入的字符串不同而選擇不同的模式,“auto”為自動(dòng)模式,該模式還可以傳入自定義參數(shù),包括旋轉(zhuǎn)速度和旋轉(zhuǎn)方向。傳入“hand”則為手動(dòng)模式,附加參數(shù)可以為手動(dòng)選擇圖片后的回調(diào)函數(shù),以及旋轉(zhuǎn)的緩動(dòng)模式。
復(fù)制代碼 代碼如下:

var Tween = {//緩動(dòng)類 默認(rèn)提供三種緩動(dòng)模式: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;
}
};

  以上就是緩動(dòng)模式類,默認(rèn)的三個(gè)模式分別為:勻速 先慢后快 先快后慢。用戶可以調(diào)用addTweenFunction方法添加自己的緩動(dòng)模式。
  更多關(guān)于緩動(dòng)的話題可以參考這兩篇文章:
  http://zengrong.net/post/1151.htm
  http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html
復(fù)制代碼 代碼如下:

/* 添加緩動(dòng)模式 */
addTweenFunction:function(name,func){
if(typeof func=='Function'||typeof func=='Object'){
Tween[name]=func;
}
},

  添加緩動(dòng)模式的參數(shù)可以為對(duì)象或方法,一次性添加同類型的一組緩動(dòng)模式建議使用對(duì)象添加。
復(fù)制代碼 代碼如下:

/* 為圖片綁定點(diǎn)擊事件處理程序 */
var bindHandlerForImgs=function(imgs,path,onSelected){
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].handler=imgSelectedHandler(imgs,path,onSelected);
util.addEventHandler(imgs[i],'click',imgs[i].handler);
}
}

  在手動(dòng)模式下,首先要做的就是為圖片綁定點(diǎn)擊的事件處理程序,點(diǎn)擊的圖片沿著橢圓軌跡旋轉(zhuǎn)移動(dòng)到最前端,并且可以觸發(fā)回調(diào)函數(shù)。
復(fù)制代碼 代碼如下:

/* 圖片選擇事件處理程序 */
var imgSelectedHandler=function(imgs,path,tween,onSelected){
return function(eve){
eve=eve||window.event;
var dir;
var angle;
var target=eve.target||eve.srcElement;
var RC=target.RC;
if(RC>=Math.PI/2&&RC<=Math.PI*3/2){
dir='ACW';
angle=3*Math.PI/2-RC;
}
else{
dir='CW';
Math.sin(RC)>=0?angle=Math.PI/2+RC:angle=RC-3*Math.PI/2;
}
(typeof timeId!='undefined')&&window.clearInterval(timeId);
rotateAngle(imgs,angle,dir,tween,onSelected);
}
}

  再看看手動(dòng)模式下的核心函數(shù),該函數(shù)作為事件處理程序,在點(diǎn)擊選擇圖片后執(zhí)行。首先判斷所點(diǎn)擊圖片處在橢圓軌跡的左邊還是右邊,如果是左邊,則旋轉(zhuǎn)方向?yàn)槟鏁r(shí)針,右邊則為順時(shí)針(為了符合最短移動(dòng)路程的原則),之后調(diào)用 rotateAngle使圖片移動(dòng)相應(yīng)角度。
復(fù)制代碼 代碼如下:

/* 旋轉(zhuǎn)指定角度 */
var rotateAngle=function(imgs,angle,dir,tween,onSelected){
var duration=1000;
var startTime=(new Date()).getTime();
dir=='CW'?dir=-1:dir=1;
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].startAngle=imgs[i].RC;
}
timeId=window.setInterval(function(){
var now=(new Date()).getTime();
if((now-startTime)>=duration){
window.clearInterval(timeId);
timeId=undefined;
onSelected=onSelected||util.emptyFunction;
onSelected();//觸發(fā)回調(diào)函數(shù);
}
for(var i=0,len=imgs.length;i<len;i++){
var path=tween(now-startTime,imgs[i].startAngle,angle,duration,dir);//通過緩動(dòng)公式計(jì)算新角度(RC)
setPos(imgs[i],path,dir);
}
},20);
}

   rotateAngle函數(shù)首先確定了旋轉(zhuǎn)所經(jīng)歷的時(shí)間,圖片的初始角度和開始旋轉(zhuǎn)的時(shí)間,然后把一切工作交給緩動(dòng)函數(shù)來計(jì)算圖片下一次的旋轉(zhuǎn)角度,緩動(dòng)函數(shù)可以是用戶設(shè)置的,也可以使用默認(rèn)的easeout(先快后慢)。如果有回調(diào)函數(shù)的話,可以在旋轉(zhuǎn)結(jié)束后觸發(fā)。
復(fù)制代碼 代碼如下:

/* 選擇上一幅圖片 */
prePho:function(onSelected){
if(this.pattern=='hand'){
onSelected=onSelected||util.emptyFunction;
var tween=tween||Tween['easeOut'];
if(typeof timeId!='undefined'){
return;
}else{
rotateAngle(this.imgs,con,'ACW',tween,onSelected);
}
}
},
/* 選擇下一幅圖片 */
nextPho:function(onSelected){
if(this.pattern=='hand'){
onSelected=onSelected||util.emptyFunction;
var tween=tween||Tween['easeOut'];
if(typeof timeId!='undefined'){
return;
}else{
rotateAngle(this.imgs,con,'CW',tween,onSelected);
}
}
},

  另外在手動(dòng)模式下,提供選擇上一張圖片和下一張圖片的接口,原理就是使所有圖片的旋轉(zhuǎn)角度為圖片之間的夾角,上一張圖片和下一張圖片的旋轉(zhuǎn)方向分別設(shè)置為逆時(shí)針和順時(shí)針。
復(fù)制代碼 代碼如下:

var rp=new rotatePhos('container');
rp.setPattern('auto',{rotateSpeed:10});//自動(dòng)模式 旋轉(zhuǎn)速度為10
rp.setPattern('hand');//手動(dòng)模式

  最后是調(diào)用方法初始化后需要設(shè)置旋轉(zhuǎn)的模式。
  說了一大堆不知道說清楚了沒有,這里提供所有源碼,有興趣的童鞋可以看看哈~
源代碼:
html:
復(fù)制代碼 代碼如下:

<div id="wrap" style="background:black;width:650px; height:250px; padding-top:20px; padding-left:20px;">
<div id="container">
<img src="pp.jpg" />
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg" />
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
<img src="pp.jpg"/>
</div>
</div>
<p>
手動(dòng)模式:<input id="select" type="radio" name="sel" value="手動(dòng)模式" onclick="rp.setPattern('hand');" checked="checked"/>
自動(dòng)模式:<input id="select" type="radio" name="sel" value="自動(dòng)模式" onclick="rp.setPattern('auto');" />
</p>
<p>
<input id="pre" type="button" value="上一張" />
<input id="next" type="button" value="下一張"/>
</p>

JS:
復(fù)制代碼 代碼如下:

var util = {
$: function(sId) { return document.getElementById(sId); },
$$:function(tagName,parent){parent=parent||document; return parent.getElementsByTagName(tagName);},
addEventHandler: function(elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type, handler, false);
}
else {
elem.attachEvent("on" + type, handler);
}
},
removeEventHandler: function(elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
}
else {
elem.detachEvent("on" + type, handler);
}
},
getComputedStyle: function(elem) {
if (elem.currentStyle)
return elem.currentStyle;
else {
return document.defaultView.getComputedStyle(elem, null);
}
},
getElementsByClassName: function(className, parentElement) {
var elems = (parentElement || document.body).getElementsByTagName("*");
var result = [];
for (i = 0; j = elems[i]; i++) {
if ((" " + j.className + " ").indexOf(" " + className + " ") != -1) {
result.push(j);
}
}
return result;
},
extend: function(destination, source) {
for (var name in source) {
destination[name] = source[name];
}
return destination;
},
emptyFunction:function(){}
};
var rotatePhos=(function(){
var rp=function(id,options){
this.init(id,options);//初始化
}
rp.prototype=(function(){
var rotate;
var imgWidth;
var imgHeight;
var scaleMargin;
var con;
var handler;
var minScale;
var Tween = {//緩動(dòng)類 默認(rèn)提供三種緩動(dòng)模式: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;
}
};
/* 改變橢圓旋轉(zhuǎn)軌跡的橫半軸長,豎半軸長*/
var changeRotateWH=function(width,height){
var halfScale=(this.maxScale-this.minScale)/2;//旋轉(zhuǎn)到中間位置時(shí)的圖片的縮放大小
rotate={};
rotate.originX=width/2;//旋轉(zhuǎn)原點(diǎn)X軸坐標(biāo)
rotate.originY=height/2;//旋轉(zhuǎn)原點(diǎn)Y軸坐標(biāo)
rotate.halfRotateWidth=(width-this.imgWidth)/2; //旋轉(zhuǎn)橫半軸長
rotate.halfRotateHeight=(height-this.imgHeight)/2; //旋轉(zhuǎn)豎半軸長
}
/* 設(shè)置圖片旋轉(zhuǎn)角和初始位置,大小 */
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);
}
}
/* 設(shè)置圖片大小和位置 */
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);//圖片在該時(shí)刻的縮放比
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);
}
/* 設(shè)置圖片位置和大小的勻速變化 */
var setImgPositionAndSize=function(img,path,direction){
direction=direction||'CW';
var dir=direction=='CW'?-1:1;
img.RC+=(path*dir);
modifyImgAngle(img);
setImgSize(img);
}
/* 修改圖片旋轉(zhuǎn)角度(保證在0-2pai之間) */
var modifyImgAngle=function(img){
(img.RC>(2*Math.PI))&&(img.RC-=2*Math.PI);
(img.RC<0)&&(img.RC+=2*Math.PI);
}
/* 設(shè)置圖片的新位置 */
var setPos=function(img,path){
img.RC=path;
modifyImgAngle(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=0.5+scaleMargin*(rotate.halfRotateHeight-rotate.halfRotateHeight*Math.sin(img.RC))/(2*rotate.halfRotateHeight);//圖片在該時(shí)刻的縮放比
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);
}
/* 旋轉(zhuǎn)指定角度 */
var rotateAngle=function(imgs,angle,dir,tween,onSelected){
var duration=1000;
var startTime=(new Date()).getTime();
dir=='CW'?dir=-1:dir=1;
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].startAngle=imgs[i].RC;
}
timeId=window.setInterval(function(){
var now=(new Date()).getTime();
if((now-startTime)>=duration){
window.clearInterval(timeId);
timeId=undefined;
onSelected=onSelected||util.emptyFunction;
onSelected();//觸發(fā)回調(diào)函數(shù);
}
for(var i=0,len=imgs.length;i<len;i++){
var path=tween(now-startTime,imgs[i].startAngle,angle,duration,dir);//通過緩動(dòng)公式計(jì)算新角度(RC)
setPos(imgs[i],path,dir);
}
},20);
}
/* 圖片選擇事件處理程序 */
var imgSelectedHandler=function(imgs,path,tween,onSelected){
return function(eve){
eve=eve||window.event;
var dir;
var angle;
var target=eve.target||eve.srcElement;
var RC=target.RC;
if(RC>=Math.PI/2&&RC<=Math.PI*3/2){
dir='ACW';
angle=3*Math.PI/2-RC;
}
else{
dir='CW';
Math.sin(RC)>=0?angle=Math.PI/2+RC:angle=RC-3*Math.PI/2;
}
(typeof timeId!='undefined')&&window.clearInterval(timeId);
rotateAngle(imgs,angle,dir,tween,onSelected);
}
}
/* 為圖片綁定點(diǎn)擊事件處理程序 */
var bindHandlerForImgs=function(imgs,path,onSelected){
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].handler=imgSelectedHandler(imgs,path,onSelected);
util.addEventHandler(imgs[i],'click',imgs[i].handler);
}
}
/* 刪除圖片上的點(diǎn)擊事件處理程序 */
var removeImgsHandler=function(imgs){
for(var i=0,len=imgs.length;i<len;i++){
if(imgs[i].handler){
util.removeEventHandler(imgs[i],'click',imgs[i].handler);
}
}
}
return{
/* 初始化 */
init:function(id,options){
var defaultOptions={
width:600, //容器寬
height:200, //容器高
imgWidth:100, //圖片寬
imgHeight:60, //圖片高
maxScale:1.5, //最大縮放倍數(shù)
minScale:0.5, //最小縮放倍數(shù)
rotateSpeed:10 //運(yùn)轉(zhuǎn)速度
}
options=util.extend(defaultOptions,options);//參數(shù)設(shè)置
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;
minScale=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);
},
/* 設(shè)置容器尺寸 */
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);//改變?nèi)萜鞒叽绾蟾淖冃D(zhuǎn)軌跡
},
/* 選擇上一幅圖片 */
prePho:function(onSelected){
if(this.pattern=='hand'){
onSelected=onSelected||util.emptyFunction;
var tween=tween||Tween['easeOut'];
if(typeof timeId!='undefined'){
return;
}else{
rotateAngle(this.imgs,con,'ACW',tween,onSelected);
}
}
},
/* 選擇下一幅圖片 */
nextPho:function(onSelected){
if(this.pattern=='hand'){
onSelected=onSelected||util.emptyFunction;
var tween=tween||Tween['easeOut'];
if(typeof timeId!='undefined'){
return;
}else{
rotateAngle(this.imgs,con,'CW',tween,onSelected);
}
}
},
/* 添加緩動(dòng)模式 */
addTweenFunction:function(name,func){
if(typeof func=='Function'||typeof func=='Object'){
Tween[name]=func;
}
},
/* 設(shè)置旋轉(zhuǎn)模式(自動(dòng)/手動(dòng))*/
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'){//自動(dòng)模式 可傳入旋轉(zhuǎn)方向:option.rotateDir 旋轉(zhuǎn)速度:option.rotateSpeed
var self=this;
var direction=option.rotateDir||'CW';//順時(shí)針:CW 逆時(shí)針: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'){//手動(dòng)模式,可傳回調(diào)函數(shù):option.onSelected 緩動(dòng)模式:option.tween
var onSelected=option.onSelected||util.emptyFunction;
var tween=Tween[tween]||Tween['easeOut'];//緩動(dòng)模式默認(rèn)為easeout
removeImgsHandler(this.imgs);
(typeof timeId!='undefined')&&window.clearInterval(timeId);
timeId=undefined;
bindHandlerForImgs(this.imgs,this.path,tween,onSelected);
}
}
}
})();
return rp;
})();
var rp=new rotatePhos('container');
//rp.setPattern('auto',{rotateSpeed:10});
rp.setPattern('hand');
document.getElementById('pre').onclick=function(){rp.prePho();};
document.getElementById('next').onclick=function(){rp.nextPho();};

完整的實(shí)現(xiàn)代碼:
復(fù)制代碼 代碼如下:

<div id="wrap" style="background: black; width: 800px; height: 350px; padding-top: 20px; padding-left: 20px; padding-right: 20px;">
<div id="container"><img src="/upload/201201/20120116231926539.jpg" alt="" /> <img src="/upload/201201/20120116231926632.jpg" alt="" /> <img src="/upload/201201/20120116231926661.jpg" alt="" /> <img src="/upload/201201/20120116231926763.jpg" alt="" /> <img src="/upload/201201/20120116231926174.jpg" alt="" /> <img src="/upload/201201/20120116231926604.jpg" alt="" /> <img src="/upload/201201/20120116231927431.jpg" alt="" /> <img src="/upload/201201/20120116231927666.JPG" alt="" /> <img src="/upload/201201/20120116231927424.jpg" alt="" /> <img src="/upload/201201/20120116231927108.jpg" alt="" /> <img src="/upload/201201/20120116231927843.jpg" alt="" /> <img src="/upload/201201/20120116231927662.bmp" alt="" /></div>
</div>
<p>手動(dòng)模式:<input id="select" onclick="rp.setPattern('hand');" type="radio" name="sel" value="手動(dòng)模式" /> 自動(dòng)模式:<input id="select" onclick="rp.setPattern('auto');" type="radio" name="sel" value="自動(dòng)模式" /></p>
<p><input id="pre" type="button" value="上一張" /> <input id="next" type="button" value="下一張" /></p>
<p>
<script type="text/javascript">// <![CDATA[
var rotatePhos = (function() {
var util = {
$: function(sId) { return document.getElementById(sId); },
$$: function(tagName, parent) { parent = parent || document; return parent.getElementsByTagName(tagName); },
addEventHandler: function(elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type, handler, false);
}
else {
elem.attachEvent("on" + type, handler);
}
},
removeEventHandler: function(elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
}
else {
elem.detachEvent("on" + type, handler);
}
},
getComputedStyle: function(elem) {
if (elem.currentStyle)
return elem.currentStyle;
else {
return document.defaultView.getComputedStyle(elem, null);
}
},
emptyFunction: function() { },
getElementsByClassName: function(className, parentElement) {
var elems = (parentElement || document.body).getElementsByTagName("*");
var result = [];
for (i = 0; j = elems[i]; i++) {
if ((" " + j.className + " ").indexOf(" " + className + " ") != -1) {
result.push(j);
}
}
return result;
},
extend: function(destination, source) {
for (var name in source) {
destination[name] = source[name];
}
return destination;
}
};
var rp = function(id, options) {
this.init(id, options); //初始化
}
rp.prototype = (function() {
var rotate;
var imgWidth;
var imgHeight;
var scaleMargin;
var con;
var handler;
var Tween = {//緩動(dòng)類 默認(rèn)提供三種緩動(dòng)模式: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;
}
};
/* 改變橢圓旋轉(zhuǎn)軌跡的橫半軸長,豎半軸長*/
var changeRotateWH = function(width, height) {
var halfScale = (this.maxScale - this.minScale) / 2; //旋轉(zhuǎn)到中間位置時(shí)的圖片的縮放大小
rotate = {};
rotate.originX = width / 2; //旋轉(zhuǎn)原點(diǎn)X軸坐標(biāo)
rotate.originY = height / 2; //旋轉(zhuǎn)原點(diǎn)Y軸坐標(biāo)
rotate.halfRotateWidth = (width - this.imgWidth) / 2; //旋轉(zhuǎn)橫半軸長
rotate.halfRotateHeight = (height - this.imgHeight) / 2; //旋轉(zhuǎn)豎半軸長
}
/* 設(shè)置圖片旋轉(zhuǎn)角和初始位置,大小 */
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);
}
}
/* 設(shè)置圖片大小 */
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 = 0.5 + scaleMargin * (rotate.halfRotateHeight - rotate.halfRotateHeight * Math.sin(img.RC)) / (2 * rotate.halfRotateHeight); //圖片在該時(shí)刻的縮放比
img.style.cssText = 'position:absolute;left:' + left + 'px;'
+ 'top:' + top + 'px;'
+ 'width:' + imgWidth * scale + 'px;'
+ 'height:' + imgHeight * scale + 'px;'
+ 'cursor:pointer;'
+ 'z-index:' + Math.round(scale * 100);
}
/* 設(shè)置圖片位置和大小的勻速變化 */
var setImgPositionAndSize = function(img, path, direction) {
direction = direction || 'CW';
var dir = direction == 'CW' ? -1 : 1;
img.RC += (path * dir);
modifyImgAngle(img);
setImgSize(img);
}
/* 修改圖片旋轉(zhuǎn)角度(保證在0-2pai之間) */
var modifyImgAngle = function(img) {
(img.RC > (2 * Math.PI)) && (img.RC -= 2 * Math.PI);
(img.RC < 0) && (img.RC += 2 * Math.PI);
}
/* 設(shè)置圖片的新位置 */
var setPos = function(img, path) {
img.RC = path;
modifyImgAngle(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 = 0.5 + scaleMargin * (rotate.halfRotateHeight - rotate.halfRotateHeight * Math.sin(img.RC)) / (2 * rotate.halfRotateHeight); //圖片在該時(shí)刻的縮放比
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);
}
/* 旋轉(zhuǎn)指定角度 */
var rotateAngle = function(imgs, angle, dir, tween, onSelected) {
var duration = 1000;
var startTime = (new Date()).getTime();
dir == 'CW' ? dir = -1 : dir = 1;
for (var i = 0, len = imgs.length; i < len; i++) {
imgs[i].startAngle = imgs[i].RC;
}
timeId = window.setInterval(function() {
var now = (new Date()).getTime();
if ((now - startTime) >= duration) {
window.clearInterval(timeId);
timeId = undefined;
onSelected = onSelected || util.emptyFunction;
onSelected(); //觸發(fā)回調(diào)函數(shù);
}
for (var i = 0, len = imgs.length; i < len; i++) {
var path = tween(now - startTime, imgs[i].startAngle, angle, duration, dir); //通過緩動(dòng)公式計(jì)算新角度(RC)
setPos(imgs[i], path, dir);
}
}, 20);
}
/* 圖片選擇事件處理程序 */
var imgSelectedHandler = function(imgs, path, tween, onSelected) {
return function(eve) {
eve = eve || window.event;
var dir;
var angle;
var target = eve.target || eve.srcElement;
var RC = target.RC;
if (RC >= Math.PI / 2 && RC <= Math.PI * 3 / 2) {
dir = 'ACW';
angle = 3 * Math.PI / 2 - RC;
}
else {
dir = 'CW';
Math.sin(RC) >= 0 ? angle = Math.PI / 2 + RC : angle = RC - 3 * Math.PI / 2;
}
(typeof timeId != 'undefined') && window.clearInterval(timeId);
rotateAngle(imgs, angle, dir, tween, onSelected);
}
}
/* 為圖片綁定點(diǎn)擊事件處理程序 */
var bindHandlerForImgs = function(imgs, path, onSelected) {
for (var i = 0, len = imgs.length; i < len; i++) {
imgs[i].handler = imgSelectedHandler(imgs, path, onSelected);
util.addEventHandler(imgs[i], 'click', imgs[i].handler);
}
}
/* 刪除圖片上的點(diǎn)擊事件處理程序 */
var removeImgsHandler = function(imgs) {
for (var i = 0, len = imgs.length; i < len; i++) {
if (imgs[i].handler) {
util.removeEventHandler(imgs[i], 'click', imgs[i].handler);
}
}
}
return {
/* 初始化 */
init: function(id, options) {
var defaultOptions = {
width: 700, //容器寬
height: 300, //容器高
imgWidth: 130, //圖片寬
imgHeight: 80, //圖片高
maxScale: 1.5, //最大縮放倍數(shù)
minScale: 0.5, //最小縮放倍數(shù)
rotateSpeed: 10 //運(yùn)轉(zhuǎn)速度
}
options = util.extend(defaultOptions, options); //參數(shù)設(shè)置
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);
},
/* 設(shè)置容器尺寸 */
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); //改變?nèi)萜鞒叽绾蟾淖冃D(zhuǎn)軌跡
},
/* 選擇上一幅圖片 */
prePho: function(onSelected) {
if (this.pattern == 'hand') {
onSelected = onSelected || util.emptyFunction;
var tween = tween || Tween['easeOut'];
if (typeof timeId != 'undefined') {
return;
} else {
rotateAngle(this.imgs, con, 'ACW', tween, onSelected);
}
}
},
/* 選擇下一幅圖片 */
nextPho: function(onSelected) {
if (this.pattern == 'hand') {
onSelected = onSelected || util.emptyFunction;
var tween = tween || Tween['easeOut'];
if (typeof timeId != 'undefined') {
return;
} else {
rotateAngle(this.imgs, con, 'CW', tween, onSelected);
}
}
},
/* 添加緩動(dòng)模式 */
addTweenFunction: function(name, func) {
if (typeof func == 'Function' || typeof func == 'Object') {
Tween[name] = func;
}
},
/* 設(shè)置旋轉(zhuǎn)模式(自動(dòng)/手動(dòng))*/
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') {//自動(dòng)模式 可傳入旋轉(zhuǎn)方向:option.rotateDir 旋轉(zhuǎn)速度:option.rotateSpeed
var self = this;
var direction = option.rotateDir || 'CW'; //順時(shí)針:CW 逆時(shí)針: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') {//手動(dòng)模式,可傳回調(diào)函數(shù):option.onSelected 緩動(dòng)模式:option.tween
var onSelected = option.onSelected || util.emptyFunction;
var tween = Tween[tween] || Tween['easeOut']; //緩動(dòng)模式默認(rèn)為easeout
removeImgsHandler(this.imgs);
(typeof timeId != 'undefined') && window.clearInterval(timeId);
timeId = undefined;
bindHandlerForImgs(this.imgs, this.path, tween, onSelected);
}
}
}
})();
return rp;
})();
var rp=new rotatePhos('container');
//rp.setPattern('auto',{rotateSpeed:10});
rp.setPattern('hand');
document.getElementById('pre').onclick=function(){rp.prePho();};
document.getElementById('next').onclick=function(){rp.nextPho();};
// ]]></script>
</p>

相關(guān)文章

最新評(píng)論