var style = this._handle.style, scale = this._scale;
style.left = Math.ceil( this._repairHandleLeft - x / scale ) + "px";
style.top = Math.ceil( this._repairHandleTop - y / scale ) + "px";
在end时,隐藏拖柄对象。
【切割模式】
“切割”就是选择的部分全透明,其他部分半透明的效果。
主要通过clip来实现,具体原理可以看图片切割效果。
为了实现切割效果,需要在init中新建一个_cropper切割层:
复制代码 代码如下:
var body = document.body,
cropper = body.insertBefore(document.createElement("img"), body.childNodes[0]);
cropper.style.display = "none";
并在load中设置这个切割层:
复制代码 代码如下:
cropper.src = image.src;
cropper.width = image.width;
cropper.height = image.height;
$$D.setStyle( cropper, {
position: "absolute",
left: rect.left + this._repairLeft + "px",
top: rect.top + this._repairTop + "px"
});
差不多是复制一个原图对象,并且绝对定位到原图对象上面。
在start时,显示切割层,并根据透明度设置原图为半透明状态。
在move时,根据大图移动的坐标设置切割层要clip的范围:
复制代码 代码如下:
var w = this._rangeWidth, h = this._rangeHeight, scale = this._scale;
x = Math.ceil( -x / scale ); y = Math.ceil( -y / scale );
this._cropper.style.clip = "rect(" + y + "px " + (x + w) + "px " + (y + h) + "px " + x + "px)";
在end时,隐藏切割层,并重新设置原图为不透明,来恢复原来的状态。
还要记得在dispose中移除切割层。
使用技巧
需要扩展的效果时才需要添加这个扩展程序。
可自行对ImageZoom._MODE进行扩展,扩展后记得在modes添加对应模式。
可以组合多个基础模式同时使用,具体参考"handle-cropper"模式。
使用说明
使用方法跟ImageZoom差不多,只是多了一个可选参考mode设置显示模式。
使用"handle"模式时,可选参数的"handle"属性可以设置拖柄对象。
使用"cropper"模式时,可选参数的"opacity"属性可以设置透明度。
使用"handle-cropper"模式时,以上两个参数都可以使用。
程序源码
复制代码 代码如下:
ImageZoom._MODE = {
//跟随
"follow": {
methods: {
init: function() {
this._stylesFollow = null;//备份样式
this._repairFollowLeft = 0;//修正坐标left
this._repairFollowTop = 0;//修正坐标top
},
load: function() {
var viewer = this._viewer, style = viewer.style, styles;
this._stylesFollow = {
left: style.left, top: style.top, position: style.position
};
viewer.style.position = "absolute";
//获取修正参数
if ( !viewer.offsetWidth ) {//隐藏
styles = { display: style.display, visibility: style.visibility };
$$D.setStyle( viewer, { display: "block", visibility: "hidden" });
}
//修正中心位置
this._repairFollowLeft = viewer.offsetWidth / 2;
this._repairFollowTop = viewer.offsetHeight / 2;
//修正offsetParent位置
if ( !/BODY|HTML/.test( viewer.offsetParent.nodeName ) ) {
var parent = viewer.offsetParent, rect = $$D.rect( parent );
this._repairFollowLeft += rect.left + parent.clientLeft;
this._repairFollowTop += rect.top + parent.clientTop;
}
if ( styles ) { $$D.setStyle( viewer, styles ); }
},
repair: function(e, pos) {
var zoom = this._zoom,
viewerWidth = this._viewerWidth,
viewerHeight = this._viewerHeight;
pos.left = ( viewerWidth / 2 - pos.left ) * ( viewerWidth / zoom.width - 1 );
pos.top = ( viewerHeight / 2 - pos.top ) * ( viewerHeight / zoom.height - 1 );
},
move: function(e) {
var style = this._viewer.style;
style.left = e.pageX - this._repairFollowLeft + "px";
style.top = e.pageY - this._repairFollowTop + "px";
},
dispose: function() {
$$D.setStyle( this._viewer, this._stylesFollow );
}
}
},
//拖柄
"handle": {
options: {//默认值
handle: ""//拖柄对象
},
methods: {
init: function() {
var handle = $$( this.options.handle );
if ( !handle ) {//没有定义的话用复制显示框代替
var body = document.body;
handle = body.insertBefore(this._viewer.cloneNode(false), body.childNodes[0]);
handle.id = "";
handle["_createbyhandle"] = true;//生成标识用于移除
}
$$D.setStyle( handle, { padding: 0, margin: 0, display: "none" } );
this._handle = handle;
this._repairHandleLeft = 0;//修正坐标left
this._repairHandleTop = 0;//修正坐标top
},
load: function() {
var handle = this._handle, rect = this._rect;
$$D.setStyle( handle, {
position: "absolute",
width: this._rangeWidth + "px",
height: this._rangeHeight + "px",
display: "block",
visibility: "hidden"
});
//获取修正参数
this._repairHandleLeft = rect.left + this._repairLeft - handle.clientLeft;
this._repairHandleTop = rect.top + this._repairTop - handle.clientTop;
//修正offsetParent位置
if ( !/BODY|HTML/.test( handle.offsetParent.nodeName ) ) {
var parent = handle.offsetParent, rect = $$D.rect( parent );
this._repairHandleLeft -= rect.left + parent.clientLeft;
this._repairHandleTop -= rect.top + parent.clientTop;
}
//隐藏
$$D.setStyle( handle, { display: "none", visibility: "visible" });
},
start: function() {
this._handle.style.display = "block";
},
move: function(e, x, y) {
var style = this._handle.style, scale = this._scale;
style.left = Math.ceil( this._repairHandleLeft - x / scale ) + "px";
style.top = Math.ceil( this._repairHandleTop - y / scale ) + "px";
},
end: function() {
this._handle.style.display = "none";
},
dispose: function() {
if( "_createbyhandle" in this._handle ){ document.body.removeChild( this._handle ); }
this._handle = null;
}
}
},
//切割
"cropper": {
options: {//默认值
opacity: .5//透明度
},
methods: {
init: function() {
var body = document.body,
cropper = body.insertBefore(document.createElement("img"), body.childNodes[0]);
cropper.style.display = "none";
this._cropper = cropper;
this.opacity = this.options.opacity;
},
load: function() {
var cropper = this._cropper, image = this._image, rect = this._rect;
cropper.src = image.src;
cropper.width = image.width;
cropper.height = image.height;
$$D.setStyle( cropper, {
position: "absolute",
left: rect.left + this._repairLeft + "px",
top: rect.top + this._repairTop + "px"
});
},
start: function() {
this._cropper.style.display = "block";
$$D.setStyle( this._image, "opacity", this.opacity );
},
move: function(e, x, y) {
var w = this._rangeWidth, h = this._rangeHeight, scale = this._scale;
x = Math.ceil( -x / scale ); y = Math.ceil( -y / scale );
this._cropper.style.clip = "rect(" + y + "px " + (x + w) + "px " + (y + h) + "px " + x + "px)";
},
end: function() {
$$D.setStyle( this._image, "opacity", 1 );
this._cropper.style.display = "none";
},
dispose: function() {
document.body.removeChild( this._cropper );
this._cropper = null;
}
}
}
}
ImageZoom.prototype._initialize = (function(){
var init = ImageZoom.prototype._initialize,
mode = ImageZoom._MODE,
modes = {
"follow": [ mode.follow ],
"handle": [ mode.handle ],
"cropper": [ mode.cropper ],
"handle-cropper": [ mode.handle, mode.cropper ]
};
return function(){
var options = arguments[2];
if ( options && options.mode && modes[ options.mode ] ) {
$$A.forEach( modes[ options.mode ], function( mode ){
//扩展options
$$.extend( options, mode.options, false );
//扩展钩子
$$A.forEach( mode.methods, function( method, name ){
$$CE.addEvent( this, name, method );
}, this );
}, this );
}
init.apply( this, arguments );
}
})();
在线演示地址
打包下载地址https://www.jb51.net/jiaoben/25809.html
出处: