原文:
http://www.cnblogs.com/cloudgamer/archive/2008/07/21/1247267.html
运行效果:
代码下载:
test.htm (19619)
<div class="post">
<div class="postcontent">
<p> </p>
<p>简单说明一下:</p>
<p>技术要点主要有层的拖动,层的缩放还有就是切割效果,预览效果。</p>
<p>总算做到了预期的效果,虽然还有很多不完善的地方,也有些功能没做出来(例如按比例缩放),</p>
<p>但也达到了最初的目的,就是在编程的过程中认识了很多以前不懂或不了解的东西。</p>
<p>程序暂时结束,说明文档稍后再写吧。</p>
<p> </p>
<p>效果:</p>
<style type="text/css">
.resize {
font-size: 0;
position: absolute;
background: #F00;
width: 5px;
height: 5px;
z-index: 500;
}
</style>
<table cellspacing="0" cellpadding="0" width="650" border="0">
<tr>
<td width="450">
<div id="bgDiv" style="width: 300px; height: 400px">
<div id="dragDiv"
style="border-right: #000000 1px solid; border-top: #000000 1px solid; border-left: #000000 1px solid; border-bottom: #000000 1px solid">
<div class="resize" id="rRightDown" style="right: 0px; bottom: 0px"></div>
<div class="resize" id="rLeftDown" style="left: 0px; bottom: 0px"></div>
<div class="resize" id="rRightUp" style="right: 0px; top: 0px"></div>
<div class="resize" id="rLeftUp" style="left: 0px; top: 0px"></div>
<div class="resize" id="rRight" style="right: 0px; top: 50%"></div>
<div class="resize" id="rLeft" style="left: 0px; top: 50%"></div>
<div class="resize" id="rUp" style="left: 50%; top: 0px"></div>
<div class="resize" id="rDown" style="left: 50%; bottom: 0px"></div>
</div>
</div>
</td>
<td>
<div id="viewDiv" style="width: 200px; height: 200px"></div>
</td>
</tr>
</table>
<script>
var $ = function(id) {
return "string" == typeof id ? document.getElementById(id) : id;
};
var isIE = (document.all) ? true : false;
function Event(e) {
var oEvent = isIE ? window.event : e;
if (isIE) {
oEvent.target = oEvent.srcElement;
oEvent.pageX = oEvent.clientX + document.documentElement.scrollLeft;
oEvent.pageY = oEvent.clientY + document.documentElement.scrollTop;
if (oEvent.type == "mouseout") {
oEvent.relatedTarget = oEvent.toElement;
} else if (oEvent.type == "mouseover") {
oEvent.relatedTarget = oEvent.fromElement;
}
oEvent.stopPropagation = function() {
this.cancelBubble = true;
}
}
return oEvent;
}
function addEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, false);
} else if (oTarget.attachEvent) {
oTarget.attachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = fnHandler;
}
};
function removeEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, false);
} else if (oTarget.detachEvent) {
oTarget.detachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = null;
}
};
var Class = {
create : function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
Object.extend = function(destination, source) {
for ( var property in source) {
destination[property] = source[property];
}
return destination;
}
//拖放程序
var Drag = Class.create();
Drag.prototype = {
//拖放对象,触发对象
initialize : function(obj, drag, options) {
var oThis = this;
this._obj = $(obj);//拖放对象
this.Drag = $(drag);//触发对象
this._x = this._y = 0;//记录鼠标相对拖放对象的位置
//事件对象(用于移除事件)
this._fM = function(e) {
oThis.Move(Event(e));
}
this._fS = function() {
oThis.Stop();
}
this.SetOptions(options);
this.Limit = !!this.options.Limit;
this.mxLeft = parseInt(this.options.mxLeft);
this.mxRight = parseInt(this.options.mxRight);
this.mxTop = parseInt(this.options.mxTop);
this.mxBottom = parseInt(this.options.mxBottom);
this.onMove = this.options.onMove;
this._obj.style.position = "absolute";
this.Drag.style.cursor = "move";
addEventHandler(this.Drag, "mousedown", function(e) {
oThis.Start(Event(e));
});
},
//设置默认属性
SetOptions : function(options) {
this.options = {//默认值
Limit :false,//是否设置限制(为true时下面mx参数有用,可以是负数)
mxLeft :0,//左边限制
mxRight :0,//右边限制
mxTop :0,//上边限制
mxBottom :0,//下边限制
onMove : function() {
}//移动时执行
};
Object.extend(this.options, options || {});
},
//准备拖动
Start : function(oEvent) {
//防止冒泡
oEvent.stopPropagation();
//记录鼠标相对拖放对象的位置
this._x = oEvent.clientX - this._obj.offsetLeft;
this._y = oEvent.clientY - this._obj.offsetTop;
//mousemove时移动 mouseup时停止
addEventHandler(document, "mousemove", this._fM);
addEventHandler(document, "mouseup", this._fS);
},
//拖动
Move : function(oEvent) {
//清除选择
if (document.selection) {
document.selection.empty();
} else {
window.getSelection().removeAllRanges();
}
//当前鼠标位置减去相对拖放对象的位置得到offset位置
var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY
- this._y;
//设置范围限制
if (this.Limit) {
//获取超出长度
var iRight = iLeft + parseInt(this._obj.style.width)
- this.mxRight, iBottom = iTop
+ parseInt(this._obj.style.height) - this.mxBottom;
//这里是先设置右边下边再设置左边上边,可能会不准确
if (iRight > 0)
iLeft -= iRight;
if (iBottom > 0)
iTop -= iBottom;
if (this.mxLeft > iLeft)
iLeft = this.mxLeft;
if (this.mxTop > iTop)
iTop = this.mxTop;
}
//设置位置
this._obj.style.left = iLeft + "px";
this._obj.style.top = iTop + "px";
//附加程序
this.onMove();
},
//停止拖动
Stop : function() {
//移除事件
removeEventHandler(document, "mousemove", this._fM);
removeEventHandler(document, "mouseup", this._fS);
}
};
//缩放程序
var Resize = Class.create();
Resize.prototype = {
//缩放对象
initialize : function(obj, options) {
var oThis = this;
this._obj = $(obj);//缩放对象
this._right = this._down = this._left = this._up = 0;//
//事件对象(用于移除事件)
this._fR = function(e) {
oThis.Resize(e);
}
this._fS = function() {
oThis.Stop();
}
this.SetOptions(options);
this.Limit = !!this.options.Limit;
this.mxLeft = parseInt(this.options.mxLeft);
this.mxRight = parseInt(this.options.mxRight);
this.mxTop = parseInt(this.options.mxTop);
this.mxBottom = parseInt(this.options.mxBottom);
this.MinWidth = parseInt(this.options.MinWidth);
this.MinHeight = parseInt(this.options.MinHeight);
this.onResize = this.options.onResize;
this._obj.style.position = "absolute";
},
//设置默认属性
SetOptions : function(options) {
this.options = {//默认值
Limit :false,//是否设置限制(为true时下面mx参数有用)
mxLeft :0,//左边限制
mxRight :0,//右边限制
mxTop :0,//上边限制
mxBottom :0,//下边限制
MinWidth :50,//最小宽度
MinHeight :50,//最小高度
onResize : function() {
}//缩放时执行
};
Object.extend(this.options, options || {});
},
//设置触发对象
Set : function(resize, side) {
var oThis = this, resize = $(resize), _fun, _cursor;
if (!resize)
return;
//根据方向设置 _fun是缩放时执行的程序 _cursor是鼠标样式
switch (side.toLowerCase()) {
case "up":
_fun = function(e) {
oThis.SetUp(e);
};
_cursor = "n-resize";
break;
case "down":
_fun = function(e) {
oThis.SetDown(e);
};
_cursor = "n-resize";
break;
case "left":
_fun = function(e) {
oThis.SetLeft(e);
};
_cursor = "e-resize";
break;
case "right":
_fun = function(e) {
oThis.SetRight(e);
};
_cursor = "e-resize";
break;
case "left-up":
_fun = function(e) {
oThis.SetLeft(e);
oThis.SetUp(e);
};
_cursor = "nw-resize";
break;
case "right-up":
_fun = function(e) {
oThis.SetRight(e);
oThis.SetUp(e);
};
_cursor = "ne-resize";
break;
case "left-down":
_fun = function(e) {
oThis.SetLeft(e);
oThis.SetDown(e);
};
_cursor = "ne-resize";
break;
case "right-down":
default:
_fun = function(e) {
oThis.SetRight(e);
oThis.SetDown(e);
};
_cursor = "nw-resize";
}
//设置触发对象
addEventHandler(resize, "mousedown", function(e) {
oThis._fun = _fun;
oThis.Start(Event(e));
});
resize.style.cursor = _cursor;
},
//准备缩放
Start : function(oEvent) {
//防止冒泡
oEvent.stopPropagation();
var _width = parseInt(this._obj.style.width)
|| this._obj.offsetWidth, _height = parseInt(this._obj.style.height)
|| this._obj.offsetHeight;
//先计算好当前边的对应另一条边的坐标 例如右边缩放时需要左边界坐标
this._left = oEvent.clientX - _width;
this._right = oEvent.clientX + _width;
this._top = oEvent.clientY - _height;
this._bottom = oEvent.clientY + _height;
//如果有范围 先计算好范围内最大宽度和高度
if (this.Limit) {
this._mxRight = this.mxRight - this._obj.offsetLeft;
this._mxDown = this.mxBottom - this._obj.offsetTop;
this._mxLeft = this.mxLeft + _width + this._obj.offsetLeft;
this._mxUp = this.mxTop + _height + this._obj.offsetTop;
}
//mousemove时缩放 mouseup时停止
addEventHandler(document, "mousemove", this._fR);
addEventHandler(document, "mouseup", this._fS);
},
//缩放
Resize : function(e) {
//清除选择
if (document.selection) {
document.selection.empty();
} else {
window.getSelection().removeAllRanges();
}
//执行缩放程序和附加程序
this._fun(Event(e));
this.onResize();
},
//右边
SetRight : function(oEvent) {
//右边和下边只要设置宽度和高度就行
//当前坐标位置减去左边的坐标等于当前宽度
var iWidth = oEvent.clientX - this._left;
//当少于最少宽度
if (iWidth < this.MinWidth) {
iWidth = this.MinWidth;
}
//当超过当前设定的最大宽度
if (this.Limit && iWidth > this._mxRight) {
iWidth = this._mxRight;
}
//设置宽度
this._obj.style.width = iWidth + "px";
},
//下边
SetDown : function(oEvent) {
var iHeight = oEvent.clientY - this._top;
if (iHeight < this.MinHeight) {
iHeight = this.MinHeight;
}
if (this.Limit && iHeight > this._mxDown) {
iHeight = this._mxDown;
}
this._obj.style.height = iHeight + "px";
},
//左边
SetLeft : function(oEvent) {
//左边和上边比较麻烦 因为还要计算left和top
//右边的坐标减去当前坐标位置等于当前宽度
var iWidth = this._right - oEvent.clientX;
//当少于最少宽度
if (iWidth < this.MinWidth) {
iWidth = this.MinWidth;
}
//当超过当前设定的最大宽度
if (this.Limit && iWidth > this._mxLeft) {
iWidth = this._mxLeft;
}
//设置宽度和left
this._obj.style.left = this._obj.offsetLeft
+ parseInt(this._obj.style.width) - iWidth + "px";
this._obj.style.width = iWidth + "px";
},
//上边
SetUp : function(oEvent) {
var iHeight = this._bottom - oEvent.clientY;
if (iHeight < this.MinHeight)
iHeight = this.MinHeight;
if (this.Limit && iHeight > this._mxUp) {
iHeight = this._mxUp;
}
this._obj.style.top = this._obj.offsetTop
+ parseInt(this._obj.style.height) - iHeight + "px";
this._obj.style.height = iHeight + "px";
},
//停止缩放
Stop : function() {
//移除事件
removeEventHandler(document, "mousemove", this._fR);
removeEventHandler(document, "mouseup", this._fS);
}
};
//图片切割
var ImgCropper = Class.create();
ImgCropper.prototype = {
//容器对象,拖放缩放对象,图片地址,宽度,高度
initialize : function(container, drag, url, width, height, options) {
var oThis = this;
this.Container = $(container);//容器对象
this.Drag = $(drag);//拖放对象
//用一个透明的层填充拖放对象 不填充的话onmousedown会失效(未知原因)
( function(o) {
o.style.width = o.style.height = "100%";
o.style.backgroundColor = "#fff";
if (isIE) {
o.style.filter = "alpha(opacity:0)";
} else {
o.style.opacity = 0;
}
})(this.Drag.appendChild(document.createElement("div")))
this._pic = this.Container.appendChild(document
.createElement("img"));//图片对象
this._cropper = this.Container.appendChild(document
.createElement("img"));//切割对象
this._cropper.onload = function() {
oThis.SetPos();
}
this.Url = url;//图片地址
this.Width = parseInt(width);//宽度
this.Height = parseInt(height);//高度
this.SetOptions(options);
this.Opacity = parseInt(this.options.Opacity);
this.dragTop = parseInt(this.options.dragTop);
this.dragLeft = parseInt(this.options.dragLeft);
this.dragWidth = parseInt(this.options.dragWidth);
this.dragHeight = parseInt(this.options.dragHeight);
//设置预览对象
this.View = $(this.options.View) || null;//预览对象
this.viewWidth = parseInt(this.options.viewWidth);
this.viewHeight = parseInt(this.options.viewHeight);
this._view = null;//预览图片对象
if (this.View) {
this._view = this.View.appendChild(document
.createElement("img"));
}
//设置拖放
this._drag = new Drag(this.Drag, this.Drag, {
Limit :true,
onMove : function() {
oThis.SetPos();
}
});
//设置缩放
this._resize = this.GetResize();
this.Init();
},
//设置默认属性
SetOptions : function(options) {
this.options = {//默认值
Opacity :50,//透明度(0到100)
//拖放位置和宽高
dragTop :0,
dragLeft :0,
dragWidth :100,
dragHeight :100,
//缩放触发对象
Right :"",
Left :"",
Up :"",
Down :"",
RightDown :"",
LeftDown :"",
RightUp :"",
LeftUp :"",
//预览对象设置
View :"",//预览对象
viewWidth :100,//预览宽度
viewHeight :100
//预览高度
};
Object.extend(this.options, options || {});
},
//初始化对象
Init : function() {
var oThis = this;
//设置容器
this.Container.style.width = this.Width + "px";
this.Container.style.height = this.Height + "px";
this.Container.style.position = "relative";
this.Container.style.overflow = "hidden";
//设置拖放对象
this.Drag.style.top = this.dragTop + "px";
this.Drag.style.left = this.dragLeft + "px";
this.Drag.style.width = this.dragWidth + "px";
this.Drag.style.height = this.dragHeight + "px";
this.Drag.style.zIndex = 200;
//设置overflow解决ie6的渲染问题
this.Drag.style.overflow = "hidden";
//设置切割对象
this._pic.src = this._cropper.src = this.Url;
this._pic.style.width = this._cropper.style.width = this.Width
+ "px";
this._pic.style.height = this._cropper.style.height = this.Height
+ "px";
this._pic.style.position = this._cropper.style.position = "absolute";
this._pic.style.top = this._pic.style.left = this._cropper.style.top = this._cropper.style.left = "0";
if (isIE) {
this._pic.style.filter = "alpha(opacity:" + this.Opacity + ")";
} else {
this._pic.style.opacity = this.Opacity / 100;
}
this._cropper.style.zIndex = 100;
//设置预览对象
if (this.View) {
this.View.style.position = "relative";
this.View.style.overflow = "hidden";
this._view.style.position = "absolute";
this._view.src = this.Url;
}
//设置拖放
this._drag.mxRight = this.Width;
this._drag.mxBottom = this.Height;
//设置缩放
if (this._resize) {
this._resize.mxRight = this.Width,
this._resize.mxBottom = this.Height
}
},
//设置获取缩放对象
GetResize : function() {
var op = this.options;
//有触发对象时才设置
if (op.RightDown || op.LeftDown || op.RightUp || op.LeftUp
|| op.Right || op.Left || op.Up || op.Down) {
var oThis = this, _resize = new Resize(this.Drag, {
Limit :true,
onResize : function() {
oThis.SetPos();
}
});
//设置缩放触发对象
if (op.RightDown) {
_resize.Set(op.RightDown, "right-down");
}
if (op.LeftDown) {
_resize.Set(op.LeftDown, "left-down");
}
if (op.RightUp) {
_resize.Set(op.RightUp, "right-up");
}
if (op.LeftUp) {
_resize.Set(op.LeftUp, "left-up");
}
if (op.Right) {
_resize.Set(op.Right, "right");
}
if (op.Left) {
_resize.Set(op.Left, "left");
}
if (op.Up) {
_resize.Set(op.Up, "up");
}
if (op.Down) {
_resize.Set(op.Down, "down");
}
return _resize;
} else {
return null;
}
},
//设置切割
SetPos : function() {
var o = this.Drag;
//按拖放对象的参数进行切割
this._cropper.style.clip = "rect(" + o.offsetTop + "px "
+ (o.offsetLeft + o.offsetWidth) + "px "
+ (o.offsetTop + o.offsetHeight) + "px " + o.offsetLeft
+ "px)";
//图片预览
if (this.View)
this.PreView();
},
//图片预览
PreView : function() {
//按比例设置宽度和高度
var o = this.Drag, h = this.viewWidth, w = h * o.offsetWidth
/ o.offsetHeight;
if (w > this.viewHeight) {
w = this.viewHeight;
h = w * o.offsetHeight / o.offsetWidth;
}
//获取对应比例尺寸
var scale = h / o.offsetHeight, ph = this.Height * scale, pw = this.Width
* scale, pt = o.offsetTop * scale, pl = o.offsetLeft
* scale, styleView = this._view.style;
//设置样式
styleView.width = pw + "px";
styleView.height = ph + "px";
styleView.top = -pt + "px ";
styleView.left = -pl + "px";
//切割预览图
styleView.clip = "rect(" + pt + "px " + (pl + w) + "px " + (pt + h)
+ "px " + pl + "px)";
}
}
var ic = new ImgCropper(
"bgDiv",
"dragDiv",
"http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_xx2.jpg",
300, 400, {
dragTop :50,
dragLeft :50,
Right :"rRight",
Left :"rLeft",
Up :"rUp",
Down :"rDown",
RightDown :"rRightDown",
LeftDown :"rLeftDown",
RightUp :"rRightUp",
LeftUp :"rLeftUp",
View :"viewDiv",
viewWidth :200,
viewHeight :200
})
</script><script>
function Scale(w, h) {
ic.Width = w;
ic.Height = h;
ic.Init();
}
function Pic(url) {
ic.Url = url;
ic.Init();
}
function Opacity(i) {
ic.Opacity = i;
ic.Init();
}
</script><br />
<br />
<div><input onclick="Scale(400,400)" type="button" value=" 增肥 "
name=""> <input onclick="Scale(300,400)" type="button"
value=" 还原 " name=""></div>
<br />
<br />
<div><input
onclick="Pic('http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_min.jpg')"
type="button" value=" 换图 " name=""> <input
onclick="Pic('http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_xx2.jpg')"
type="button" value=" 还原 " name=""></div>
<br />
<br />
<div><input onclick="Opacity(0)" type="button" value=" 透明 "
name=""> <input onclick="Opacity(50)" type="button"
value=" 还原 " name=""></div>
</div>
2008-07-26_065201.gif test.htm