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

cloudgamer出品ImageZoom 圖片放大效果

 更新時間:2010年04月01日 17:22:42   作者:  
這個效果也叫放大鏡效果,最早好像在ppg出現(xiàn)的,之后就有了很多仿制品出來了。
一般用于放大查看商品圖片,在凡客,京東商城,阿里巴巴等都有類似的效果。
好處是能在原圖附近對圖片進行局部放大查看,而且可以通過鼠標控制查看的部位。
前一陣子看到sohighthesky的圖片放大效果,心血來潮自己也寫一個看看。
這個程序有以下特點:
1,支持使用原圖放大或新圖片設置大圖;
2,大圖完成載入前使用原圖放大代替,減少操作等待時間;
3,支持鼠標滾動縮放大圖;
4,可以通過設置顯示范圍或顯示框大小設置顯示尺寸;
5,可以設置是否自動隱藏顯示框;
6,支持插件形式的擴展來實現(xiàn)更多的功能(下一篇再詳細介紹)。
兼容:ie6/7/8, firefox 3.6.2, opera 10.51, safari 4.0.4, chrome 4.1
復制代碼 代碼如下:

var styles;
if ( !viewer.clientWidth ) {
var style = viewer.style;
styles = {
display: style.display,
position: style.position,
visibility: style.visibility
};
$$D.setStyle( viewer, {
display: "block", position: "absolute", visibility: "hidden"
});
}
this._viewerWidth = viewer.clientWidth;
this._viewerHeight = viewer.clientHeight;
if ( styles ) { $$D.setStyle( viewer, styles ); }
rangeWidth = Math.ceil( this._viewerWidth / scale );
rangeHeight = Math.ceil( this._viewerHeight / scale );

注意,顯示范圍是通過clientWidth/clientHeight來獲取的。
如果顯示框是display為none的隱藏狀態(tài),就不能直接獲取clientWidth/clientHeight。
這種情況下,程序用以下方法獲?。?
1,記錄display/position/visibility的原始值;
2,分別設為"block"/"absolute"/"hidden",這是既能隱藏也能占位的狀態(tài);
3,獲取參數(shù);
4,重新設回原始值,恢復原來的狀態(tài)。
得到顯示范圍后,再配合比例就能得到范圍參數(shù)了。
ps:這是通用的獲取不占位元素尺寸參數(shù)的方法,jquery的css也是用這個方法獲取width/height的。
比例計算后可能會得到小數(shù),而尺寸大小只能是整數(shù),程序一律使用Math.ceil來取整。
【放大效果】
所有東西都設置好后,就可以執(zhí)行start設置觸發(fā)程序了。
程序會自動執(zhí)行start方法,里面主要是給原圖對象的mouseover/mousemove綁定_start程序:
var image = this._image, START = this._START;
$$E.addEvent( image, "mouseover", START );
$$E.addEvent( image, "mousemove", START );
分別對應移入原圖對象和在原圖對象上移動的情況。
ps:如果使用attachEvent的話還要注意重復綁定同一函數(shù)的問題,這里的addEvent就沒有這個問題。
綁定的_start程序,主要是進行一些事件的解綁和綁定:
復制代碼 代碼如下:

$$E.removeEvent( image, "mouseover", this._START );
$$E.removeEvent( image, "mousemove", this._START );
$$E.addEvent( document, "mousemove", this._MOVE );
$$E.addEvent( document, "mouseout", this._OUT );

為了在移出窗口時能結束放大效果,給document的mouseout綁定了_OUT程序:
復制代碼 代碼如下:

this._OUT = $$F.bindAsEventListener( function(e){
if ( !e.relatedTarget ) this._END();
}, this );

當鼠標移出document會觸發(fā)mouseout,如果當前relatedTarget是null的話,就延時執(zhí)行_end結束程序:
var oThis = this, END = function(){ oThis._end(); };
this._END = function(){ oThis._timer = setTimeout( END, oThis.delay ); };
在_end程序中,會先執(zhí)行stop方法,在里面移除所有可能綁定的事件,再執(zhí)行start方法繼續(xù)等待觸發(fā)。
而mousemove綁定的_move移動程序,主要用來實現(xiàn)鼠標移動到哪里就放大哪里的功能。
為適應更多的情況(例如擴展篇的其他模式),把它綁定到document上,但也因此不能用mouseout事件來觸發(fā)移出程序。
程序通過鼠標和原圖的坐標比較,來判斷鼠標是否移出原圖對象范圍:
復制代碼 代碼如下:

var x = e.pageX, y = e.pageY, rect = this._rect;
if ( x < rect.left || x > rect.right || y < rect.top || y > rect.bottom ) {
this._END();
} else {
...
}

如果鼠標移出原圖對象的話,就執(zhí)行_END結束放大效果。
如果鼠標在原圖對象上移動,就計算坐標,并通過_repair程序把坐標轉化成定位需要的值。
最后設置大圖的left/top定位使顯示框顯示要放大的部位。
ps:我嘗試過用scrollLeft/scrollTop來做定位,但發(fā)現(xiàn)這樣在ie中會像鋸齒那樣移動,放得越大越明顯,所以放棄。
【鼠標滾動縮放】
如果設置mouse屬性為true,就會開啟鼠標滾動縮放功能。
在執(zhí)行放大效果期間,可以通過滾動鼠標滾輪對大圖進行縮放處理。
其實就是根據(jù)滾輪動參數(shù)的變化來修改放大比例。
關于鼠標滾動事件,在slider中也提過,不過那時只分析了ie和ff的區(qū)別,這里再分析一下。
首先ie是用mousewheel綁定事件的,使用event的wheelDelta來獲取滾動參數(shù)。
其他瀏覽器用以下代碼測試:
復制代碼 代碼如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body style="height:1000px;">
<script>
function test(e){ alert(e.type+":"+e.detail+"_"+e.wheelDelta) }
document.addEventListener( "DOMMouseScroll", test, false );
document.addEventListener( "mousewheel", test, false );
</script>
</body>
</html>

向下滾動一下,可以得到以下結果:
ff:DOMMouseScroll:3_undefined
opera:mousewheel:3_-120
chrome/safari:mousewheel:0_-120
可以看到事件的綁定,ff只支持DOMMouseScroll,其他就只支持mousewheel。
而滾動參數(shù)的獲取,ff只支持detail,opera兩種都支持,chrome/safari就支持wheelDelta。
ps:不明白chrome/safari的detail為什么是0,有其他用途?
而DOMMouseScroll跟mousewheel還有一個不同是前者不能直接綁定元素,后者可以。
即可以elem.onmousewheel,但不能elem.onDOMMouseScroll。
根據(jù)以上分析,在_start程序里是這樣把_mouse程序綁定到document的滾動事件中:
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE );
在_mouse程序里面根據(jù)滾動參數(shù)和自定義的rate縮放比率得到新的放大比例:
this._scale += ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * this.rate;
修改比例時,程序參數(shù)也需要重新計算。
由于_rangeWidth/_rangeHeight會影響計算的過程,要重新恢復成自定義的默認值:
var opt = this.options;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
然后執(zhí)行_initSize和_initData重新設置尺寸和參數(shù),再執(zhí)行_move重新定位。
最后記得用preventDefault防止觸發(fā)頁面滾動。
使用技巧
【圖片設置】
程序支持大圖使用原圖放大或用新大圖。
如果用新大圖而且圖片比較大的話,強烈建議設置放大比例,這樣程序會自動在大圖載入前先使用原圖放大,這樣就不用等待大圖加載完成。
還要注意新大圖本身的寬高比例要跟原圖一致,否則就對不準坐標了,使用原圖放大就沒有這個問題。
【顯示框設置】
有兩個方法可以設置顯示框的尺寸:
要固定顯示范圍的話,先設置rangeWidth/rangeHeight,程序會根據(jù)顯示范圍和放大比例計算顯示框的尺寸;
要用顯示框當前的尺寸來顯示的話,只要不設置rangeWidth/rangeHeight或設為0就可以了。
【reset】
由于各個屬性和對象之間有很多的關聯(lián),很多屬性不能直接修改。
程序設置了一個reset方法專門用來修改這類屬性的。
如果程序加載完成后又修改了影響程序計算的樣式,例如原圖大小,顯示框大小等,也要執(zhí)行一次reset來重新設置參數(shù)和屬性。
【浮動定位】
程序沒有設置顯示框浮動定位的功能,需要的話可以自行添加。
簡單的定位可以參考實例的方法,還要小心覆蓋select的問題。
如果要更復雜的浮動定位,可以參考“浮動定位提示效果”。
【opera的bug】
測試中發(fā)現(xiàn)opera 10.10有兩個bug。
分別是img元素設置透明時會看到背景圖,用js修改鼠標樣式會有問題。
不過這兩個問題在10.50都已經(jīng)修復了,還沒升級的趕快升啦。
【maxthon的bug】
用maxthon 2.5.1測試時發(fā)現(xiàn)一個問題,測試以下代碼:
復制代碼 代碼如下:

<div id="t" style="width:50px;"></div>
<script>
var t=document.getElementById("t");
t.clientWidth;
t.style.display="none";
alert(t.clientWidth);
</script>

一般來說用display隱藏后,clientWidth應該是0的,但maxthon貌似沒有處理這個情況。
這會影響到程序中clientWidth的判斷,不過對一般使用沒什么影響。
我已經(jīng)提交了這個問題,不知會不會處理。
使用說明
實例化時,必須有一個img元素作為原圖對象,和一個容器作為顯示框:
var iz = new ImageZoom( "idImage", "idViewer" );
可選參數(shù)用來設置系統(tǒng)的默認屬性,包括:
屬性: 默認值//說明
mode: "simple",//模式
scale: 0,//比例(大圖/原圖)
max: 10,//最大比例
min: 1.5,//最小比例
originPic: "",//原圖地址
zoomPic: "",//大圖地址
rangeWidth: 0,//顯示范圍寬度
rangeHeight:0,//顯示范圍高度
delay: 20,//延遲結束時間
autoHide: true,//是否自動隱藏
mouse: false,//鼠標縮放
rate: .2,//鼠標縮放比率
onLoad: $$.emptyFunction,//加載完成時執(zhí)行
onStart: $$.emptyFunction,//開始放大時執(zhí)行
onMove: $$.emptyFunction,//放大移動時執(zhí)行
onEnd: $$.emptyFunction//放大結束時執(zhí)行
其中模式的使用在下一篇擴展篇再說明。
初始化后,scale、max、min、originPic、zoomPic、rangeWidth、rangeHeight這些屬性需要用reset方法來修改。
還提供了以下方法:
start:開始放大程序(程序會自動執(zhí)行);
stop:停止放大程序;
reset:修改設置;
dispose:銷毀程序。
程序源碼
復制代碼 代碼如下:

var ImageZoom = function(image, viewer, options) {
this._initialize( image, viewer, options );
this._initMode( this.options.mode );
this._oninit();
this._initLoad();
};
ImageZoom.prototype = {
//初始化程序
_initialize: function(image, viewer, options) {
this._image = $$(image);//原圖
this._zoom = document.createElement("img");//顯示圖
this._viewer = $$(viewer);//顯示框
this._viewerWidth = 0;//顯示框寬
this._viewerHeight = 0;//顯示框高
this._preload = new Image();//預載對象
this._rect = null;//原圖坐標
this._repairLeft = 0;//顯示圖x坐標修正
this._repairTop = 0;//顯示圖y坐標修正
this._rangeWidth = 0;//顯示范圍寬度
this._rangeHeight = 0;//顯示范圍高度
this._timer = null;//計時器
this._loaded = false;//是否加載
this._substitute = false;//是否替換
var opt = this._setOptions(options);
this._scale = opt.scale;
this._max = opt.max;
this._min = opt.min;
this._originPic = opt.originPic;
this._zoomPic = opt.zoomPic;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
this.delay = opt.delay;
this.autoHide = opt.autoHide;
this.mouse = opt.mouse;
this.rate = opt.rate;
this.onLoad = opt.onLoad;
this.onStart = opt.onStart;
this.onMove = opt.onMove;
this.onEnd = opt.onEnd;
var oThis = this, END = function(){ oThis._end(); };
this._END = function(){ oThis._timer = setTimeout( END, oThis.delay ); };
this._START = $$F.bindAsEventListener( this._start, this );
this._MOVE = $$F.bindAsEventListener( this._move, this );
this._MOUSE = $$F.bindAsEventListener( this._mouse, this );
this._OUT = $$F.bindAsEventListener( function(e){
if ( !e.relatedTarget ) this._END();
}, this );
},
//設置默認屬性
_setOptions: function(options) {
this.options = {//默認值
mode: "simple",//模式
scale: 0,//比例(大圖/原圖)
max: 10,//最大比例
min: 1.5,//最小比例
originPic: "",//原圖地址
zoomPic: "",//大圖地址
rangeWidth: 0,//顯示范圍寬度
rangeHeight:0,//顯示范圍高度
delay: 20,//延遲結束時間
autoHide: true,//是否自動隱藏
mouse: false,//鼠標縮放
rate: .2,//鼠標縮放比率
onLoad: $$.emptyFunction,//加載完成時執(zhí)行
onStart: $$.emptyFunction,//開始放大時執(zhí)行
onMove: $$.emptyFunction,//放大移動時執(zhí)行
onEnd: $$.emptyFunction//放大結束時執(zhí)行
};
return $$.extend(this.options, options || {});
},
//根據(jù)模式初始化函數(shù)屬性
_initMode: function(mode) {
mode = $$.extend({
options:{},
init: $$.emptyFunction,
load: $$.emptyFunction,
start: $$.emptyFunction,
end: $$.emptyFunction,
move: $$.emptyFunction,
dispose:$$.emptyFunction
}, (ImageZoom._MODE || {})[ mode.toLowerCase() ] || {} );
this.options = $$.extend( mode.options, this.options );
this._oninit = mode.init;
this._onload = mode.load;
this._onstart = mode.start;
this._onend = mode.end;
this._onmove = mode.move;
this._ondispose = mode.dispose;
},
//初始化加載
_initLoad: function() {
var image = this._image, originPic = this._originPic,
useOrigin = !this._zoomPic && this._scale,
loadImage = $$F.bind( useOrigin ? this._loadOriginImage : this._loadImage, this );
//設置自動隱藏
if ( this.autoHide ) { this._viewer.style.display = "none"; }
//先加載原圖
if ( originPic && originPic != image.src ) {//使用自定義地址
image.onload = loadImage;
image.src = originPic;
} else if ( image.src ) {//使用元素地址
if ( !image.complete ) {//未載入完
image.onload = loadImage;
} else {//已經(jīng)載入
loadImage();
}
} else {
return;//沒有原圖地址
}
//加載大圖
if ( !useOrigin ) {
var preload = this._preload, zoomPic = this._zoomPic || image.src,
loadPreload = $$F.bind( this._loadPreload, this );
if ( zoomPic != preload.src ) {//新地址重新加載
preload.onload = loadPreload;
preload.src = zoomPic;
} else {//正在加載
if ( !preload.complete ) {//未載入完
preload.onload = loadPreload;
} else {//已經(jīng)載入
this._loadPreload();
}
}
}
},
//原圖放大加載程序
_loadOriginImage: function() {
this._image.onload = null;
this._zoom.src = this._image.src;
this._initLoaded();
},
//原圖加載程序
_loadImage: function() {
this._image.onload = null;
if ( this._loaded ) {//大圖已經(jīng)加載
this._initLoaded();
} else {
this._loaded = true;
if ( this._scale ) {//有自定義比例才用原圖放大替換大圖
this._substitute = true;
this._zoom.src = this._image.src;
this._initLoaded();
}
}
},
//大圖預載程序
_loadPreload: function() {
this._preload.onload = null;
this._zoom.src = this._preload.src;
if ( this._loaded ) {//原圖已經(jīng)加載
//沒有使用替換
if ( !this._substitute ) { this._initLoaded(); }
} else {
this._loaded = true;
}
},
//初始化加載設置
_initLoaded: function(src) {
//初始化顯示圖
this._initSize();
//初始化顯示框
this._initViewer();
//初始化數(shù)據(jù)
this._initData();
//開始執(zhí)行
this._onload();
this.onLoad();
this.start();
},
//初始化顯示圖尺寸
_initSize: function() {
var zoom = this._zoom, image = this._image, scale = this._scale;
if ( !scale ) { scale = this._preload.width / image.width; }
this._scale = scale = Math.min( Math.max( this._min, scale ), this._max );
//按比例設置顯示圖大小
zoom.width = Math.ceil( image.width * scale );
zoom.height = Math.ceil( image.height * scale );
},
//初始化顯示框
_initViewer: function() {
var zoom = this._zoom, viewer = this._viewer;
//設置樣式
var styles = { padding: 0, overflow: "hidden" }, p = $$D.getStyle( viewer, "position" );
if ( p != "relative" && p != "absolute" ){ styles.position = "relative"; };
$$D.setStyle( viewer, styles );
zoom.style.position = "absolute";
//插入顯示圖
if ( !$$D.contains( viewer, zoom ) ){ viewer.appendChild( zoom ); }
},
//初始化數(shù)據(jù)
_initData: function() {
var zoom = this._zoom, image = this._image, viewer = this._viewer,
scale = this._scale, rangeWidth = this._rangeWidth, rangeHeight = this._rangeHeight;
//原圖坐標
this._rect = $$D.rect( image );
//修正參數(shù)
this._repairLeft = image.clientLeft + parseInt($$D.getStyle( image, "padding-left" ));
this._repairTop = image.clientTop + parseInt($$D.getStyle( image, "padding-top" ));
//設置范圍參數(shù)和顯示框大小
if ( rangeWidth > 0 && rangeHeight > 0 ) {
rangeWidth = Math.ceil( rangeWidth );
rangeHeight = Math.ceil( rangeHeight );
this._viewerWidth = Math.ceil( rangeWidth * scale );
this._viewerHeight = Math.ceil( rangeHeight * scale );
$$D.setStyle( viewer, {
width: this._viewerWidth + "px",
height: this._viewerHeight + "px"
});
} else {
var styles;
if ( !viewer.clientWidth ) {//隱藏
var style = viewer.style;
styles = {
display: style.display,
position: style.position,
visibility: style.visibility
};
$$D.setStyle( viewer, {
display: "block", position: "absolute", visibility: "hidden"
});
}
this._viewerWidth = viewer.clientWidth;
this._viewerHeight = viewer.clientHeight;
if ( styles ) { $$D.setStyle( viewer, styles ); }
rangeWidth = Math.ceil( this._viewerWidth / scale );
rangeHeight = Math.ceil( this._viewerHeight / scale );
}
this._rangeWidth = rangeWidth;
this._rangeHeight = rangeHeight;
},
//開始
_start: function() {
clearTimeout( this._timer );
var viewer = this._viewer, image = this._image, scale = this._scale;
viewer.style.display = "block";
this._onstart();
this.onStart();
$$E.removeEvent( image, "mouseover", this._START );
$$E.removeEvent( image, "mousemove", this._START );
$$E.addEvent( document, "mousemove", this._MOVE );
$$E.addEvent( document, "mouseout", this._OUT );
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE );
},
//移動
_move: function(e) {
clearTimeout( this._timer );
var x = e.pageX, y = e.pageY, rect = this._rect;
if ( x < rect.left || x > rect.right || y < rect.top || y > rect.bottom ) {
this._END();//移出原圖范圍
} else {
var zoom = this._zoom,
pos = this._repair(
x - rect.left - this._repairLeft,
y - rect.top - this._repairTop
);
this._onmove( e, pos );
//設置定位
zoom.style.left = pos.left + "px";
zoom.style.top = pos.top + "px";
this.onMove();
}
},
//修正坐標
_repair: function(x, y) {
var scale = this._scale, zoom = this._zoom,
viewerWidth = this._viewerWidth,
viewerHeight = this._viewerHeight;
//修正坐標
x = Math.ceil( viewerWidth / 2 - x * scale );
y = Math.ceil( viewerHeight / 2 - y * scale );
//范圍限制
x = Math.min( Math.max( x, viewerWidth - zoom.width ), 0 );
y = Math.min( Math.max( y, viewerHeight - zoom.height ), 0 );
return { left: x, top: y };
},
//結束
_end: function() {
this._onend();
this.onEnd();
if ( this.autoHide ) { this._viewer.style.display = "none"; }
this.stop();
this.start();
},
//鼠標縮放
_mouse: function(e) {
this._scale += ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * this.rate;
var opt = this.options;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
this._initSize();
this._initData();
this._move(e);
e.preventDefault();
},
//開始
start: function() {
if ( this._viewerWidth && this._viewerHeight ) {
var image = this._image, START = this._START;
$$E.addEvent( image, "mouseover", START );
$$E.addEvent( image, "mousemove", START );
}
},
//停止
stop: function() {
clearTimeout( this._timer );
$$E.removeEvent( this._image, "mouseover", this._START );
$$E.removeEvent( this._image, "mousemove", this._START );
$$E.removeEvent( document, "mousemove", this._MOVE );
$$E.removeEvent( document, "mouseout", this._OUT );
$$E.removeEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE );
},
//修改設置
reset: function(options) {
this.stop();
var viewer = this._viewer, zoom = this._zoom;
if ( $$D.contains( viewer, zoom ) ) { viewer.removeChild( zoom ); }
var opt = $$.extend( this.options, options || {} );
this._scale = opt.scale;
this._max = opt.max;
this._min = opt.min;
this._originPic = opt.originPic;
this._zoomPic = opt.zoomPic;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
//重置屬性
this._loaded = this._substitute = false;
this._rect = null;
this._repairLeft = this._repairTop =
this._viewerWidth = this._viewerHeight = 0;
this._initLoad();
},
//銷毀程序
dispose: function() {
this._ondispose();
this.stop();
if ( $$D.contains( this._viewer, this._zoom ) ) {
this._viewer.removeChild( this._zoom );
}
this._image.onload = this._preload.onload =
this._image = this._preload = this._zoom = this._viewer =
this.onLoad = this.onStart = this.onMove = this.onEnd =
this._START = this._MOVE = this._END = this._OUT = null
}
}

轉載請注明出處:http://www.cnblogs.com/cloudgamer/

如有任何建議或疑問,歡迎留言討論。
打包下載地址

相關文章

最新評論