发新话题
移动帖子 加入精华 加入置顶 加入收藏 关注此帖

JavaScript 图片切割效果(带拖放、缩放效果)





JavaScript 图片切割效果(带拖放、缩放效果)

原文: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
快乐渡过每一天,减肥坚持每一天



编辑 回复 快速回复 TOP


Re:JavaScript 图片切割效果(带拖放、缩放效果)

快乐渡过每一天,减肥坚持每一天
编辑 回复 快速回复 TOP
发新话题