Welcome 微信登录

首页 / 脚本样式 / JavaScript / JavaScript实现选择框按比例拖拉缩放的方法

本文实例讲述了JavaScript实现选择框按比例拖拉缩放的方法。分享给大家供大家参考。具体如下:
这里通过javascript实现可以像PS一样拉出一个选择框的效果。里面的很多方法都是我们值得学习的。
运行效果如下图所示:

具体代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>JavaScript拖拉缩放效果</title></head><body><script>var isIE = (document.all) ? true : false;var $ = function (id) {return "string" == typeof id ? document.getElementById(id) : id;};var Class = {create: function() {return function() { this.initialize.apply(this, arguments); }}}var Extend = function(destination, source) {for (var property in source) {destination[property] = source[property];}}var Bind = function(object, fun) {return function() {return fun.apply(object, arguments);}}var BindAsEventListener = function(object, fun) {var args = Array.prototype.slice.call(arguments).slice(2);return function(event) {return fun.apply(object, [event || window.event].concat(args));}}var CurrentStyle = function(element){return element.currentStyle || document.defaultView.getComputedStyle(element, null);}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 Resize = Class.create();Resize.prototype = {//缩放对象initialize: function(obj, options) {this._obj = $(obj);//缩放对象this._styleWidth = this._styleHeight = this._styleLeft = this._styleTop = 0;//样式参数this._sideRight = this._sideDown = this._sideLeft = this._sideUp = 0;//坐标参数this._fixLeft = this._fixTop = 0;//定位参数this._scaleLeft = this._scaleTop = 0;//定位坐标this._mxSet = function(){};//范围设置程序this._mxRightWidth = this._mxDownHeight = this._mxUpHeight = this._mxLeftWidth = 0;//范围参数this._mxScaleWidth = this._mxScaleHeight = 0;//比例范围参数this._fun = function(){};//缩放执行程序//获取边框宽度var _style = CurrentStyle(this._obj);this._borderX = (parseInt(_style.borderLeftWidth) || 0) + (parseInt(_style.borderRightWidth) || 0);this._borderY = (parseInt(_style.borderTopWidth) || 0) + (parseInt(_style.borderBottomWidth) || 0);//事件对象(用于绑定移除事件)this._fR = BindAsEventListener(this, this.Resize);this._fS = Bind(this, this.Stop);this.SetOptions(options);//范围限制this.Max = !!this.options.Max;this._mxContainer = $(this.options.mxContainer) || null;this.mxLeft = Math.round(this.options.mxLeft);this.mxRight = Math.round(this.options.mxRight);this.mxTop = Math.round(this.options.mxTop);this.mxBottom = Math.round(this.options.mxBottom);//宽高限制this.Min = !!this.options.Min;this.minWidth = Math.round(this.options.minWidth);this.minHeight = Math.round(this.options.minHeight);//按比例缩放this.Scale = !!this.options.Scale;this.Ratio = Math.max(this.options.Ratio, 0);this.onResize = this.options.onResize;this._obj.style.position = "absolute";!this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative"); }, //设置默认属性 SetOptions: function(options) { this.options = {//默认值Max:false,//是否设置范围限制(为true时下面mx参数有用)mxContainer:"",//指定限制在容器内mxLeft:0,//左边限制mxRight:9999,//右边限制mxTop:0,//上边限制mxBottom:9999,//下边限制Min:false,//是否最小宽高限制(为true时下面min参数有用)minWidth:50,//最小宽度minHeight:50,//最小高度Scale:false,//是否按比例缩放Ratio:0,//缩放比例(宽/高)onResize:function(){}//缩放时执行 }; Extend(this.options, options || {}); }, //设置触发对象 Set: function(resize, side) {var resize = $(resize), fun;if(!resize) return;//根据方向设置switch (side.toLowerCase()) {case "up" :fun = this.Up;break;case "down" :fun = this.Down;break;case "left" :fun = this.Left;break;case "right" :fun = this.Right;break;case "left-up" :fun = this.LeftUp;break;case "right-up" :fun = this.RightUp;break;case "left-down" :fun = this.LeftDown;break;case "right-down" :default :fun = this.RightDown;};//设置触发对象addEventHandler(resize, "mousedown", BindAsEventListener(this, this.Start, fun)); }, //准备缩放 Start: function(e, fun, touch) {//防止冒泡(跟拖放配合时设置)e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);//设置执行程序this._fun = fun;//样式参数值this._styleWidth = this._obj.clientWidth;this._styleHeight = this._obj.clientHeight;this._styleLeft = this._obj.offsetLeft;this._styleTop = this._obj.offsetTop;//四条边定位坐标this._sideLeft = e.clientX - this._styleWidth;this._sideRight = e.clientX + this._styleWidth;this._sideUp = e.clientY - this._styleHeight;this._sideDown = e.clientY + this._styleHeight;//top和left定位参数this._fixLeft = this._styleLeft + this._styleWidth;this._fixTop = this._styleTop + this._styleHeight;//缩放比例if(this.Scale){//设置比例this.Ratio = Math.max(this.Ratio, 0) || this._styleWidth / this._styleHeight;//left和top的定位坐标this._scaleLeft = this._styleLeft + this._styleWidth / 2;this._scaleTop = this._styleTop + this._styleHeight / 2;};//范围限制if(this.Max){//设置范围参数var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;//如果设置了容器,再修正范围参数if(!!this._mxContainer){mxLeft = Math.max(mxLeft, 0);mxTop = Math.max(mxTop, 0);mxRight = Math.min(mxRight, this._mxContainer.clientWidth);mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);};//根据最小值再修正mxRight = Math.max(mxRight, mxLeft + (this.Min ? this.minWidth : 0) + this._borderX);mxBottom = Math.max(mxBottom, mxTop + (this.Min ? this.minHeight : 0) + this._borderY);//由于转向时要重新设置所以写成function形式this._mxSet = function(){this._mxRightWidth = mxRight - this._styleLeft - this._borderX;this._mxDownHeight = mxBottom - this._styleTop - this._borderY;this._mxUpHeight = Math.max(this._fixTop - mxTop, this.Min ? this.minHeight : 0);this._mxLeftWidth = Math.max(this._fixLeft - mxLeft, this.Min ? this.minWidth : 0);};this._mxSet();//有缩放比例下的范围限制if(this.Scale){this._mxScaleWidth = Math.min(this._scaleLeft - mxLeft, mxRight - this._scaleLeft - this._borderX) * 2;this._mxScaleHeight = Math.min(this._scaleTop - mxTop, mxBottom - this._scaleTop - this._borderY) * 2;};};//mousemove时缩放 mouseup时停止addEventHandler(document, "mousemove", this._fR);addEventHandler(document, "mouseup", this._fS);if(isIE){addEventHandler(this._obj, "losecapture", this._fS);this._obj.setCapture();}else{addEventHandler(window, "blur", this._fS);e.preventDefault();}; }, //缩放 Resize: function(e) {//清除选择window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();//执行缩放程序this._fun(e);//设置样式,变量必须大于等于0否则ie出错with(this._obj.style){width = this._styleWidth + "px"; height = this._styleHeight + "px";top = this._styleTop + "px"; left = this._styleLeft + "px";}//附加程序this.onResize(); }, //缩放程序 //上 Up: function(e) {this.RepairY(this._sideDown - e.clientY, this._mxUpHeight);this.RepairTop();this.TurnDown(this.Down); }, //下 Down: function(e) {this.RepairY(e.clientY - this._sideUp, this._mxDownHeight);this.TurnUp(this.Up); }, //右 Right: function(e) {this.RepairX(e.clientX - this._sideLeft, this._mxRightWidth);this.TurnLeft(this.Left); }, //左 Left: function(e) {this.RepairX(this._sideRight - e.clientX, this._mxLeftWidth);this.RepairLeft();this.TurnRight(this.Right); }, //右下 RightDown: function(e) {this.RepairAngle(e.clientX - this._sideLeft, this._mxRightWidth,e.clientY - this._sideUp, this._mxDownHeight);this.TurnLeft(this.LeftDown) || this.Scale || this.TurnUp(this.RightUp); }, //右上 RightUp: function(e) {this.RepairAngle(e.clientX - this._sideLeft, this._mxRightWidth,this._sideDown - e.clientY, this._mxUpHeight);this.RepairTop();this.TurnLeft(this.LeftUp) || this.Scale || this.TurnDown(this.RightDown); }, //左下 LeftDown: function(e) {this.RepairAngle(this._sideRight - e.clientX, this._mxLeftWidth,e.clientY - this._sideUp, this._mxDownHeight);this.RepairLeft();this.TurnRight(this.RightDown) || this.Scale || this.TurnUp(this.LeftUp); }, //左上 LeftUp: function(e) {this.RepairAngle(this._sideRight - e.clientX, this._mxLeftWidth,this._sideDown - e.clientY, this._mxUpHeight);this.RepairTop(); this.RepairLeft();this.TurnRight(this.RightUp) || this.Scale || this.TurnDown(this.LeftDown); }, //水平方向 RepairX: function(iWidth, mxWidth) {iWidth = this.RepairWidth(iWidth, mxWidth);if(this.Scale){var iHeight = this.RepairScaleHeight(iWidth);if(this.Max && iHeight > this._mxScaleHeight){iHeight = this._mxScaleHeight;iWidth = this.RepairScaleWidth(iHeight);}else if(this.Min && iHeight < this.minHeight){var tWidth = this.RepairScaleWidth(this.minHeight);if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; }}this._styleHeight = iHeight;this._styleTop = this._scaleTop - iHeight / 2;}this._styleWidth = iWidth; }, //垂直方向 RepairY: function(iHeight, mxHeight) {iHeight = this.RepairHeight(iHeight, mxHeight);if(this.Scale){var iWidth = this.RepairScaleWidth(iHeight);if(this.Max && iWidth > this._mxScaleWidth){iWidth = this._mxScaleWidth;iHeight = this.RepairScaleHeight(iWidth);}else if(this.Min && iWidth < this.minWidth){var tHeight = this.RepairScaleHeight(this.minWidth);if(tHeight < mxHeight){ iWidth = this.minWidth; iHeight = tHeight; }}this._styleWidth = iWidth;this._styleLeft = this._scaleLeft - iWidth / 2;}this._styleHeight = iHeight; }, //对角方向 RepairAngle: function(iWidth, mxWidth, iHeight, mxHeight) {iWidth = this.RepairWidth(iWidth, mxWidth);if(this.Scale){iHeight = this.RepairScaleHeight(iWidth);if(this.Max && iHeight > mxHeight){iHeight = mxHeight;iWidth = this.RepairScaleWidth(iHeight);}else if(this.Min && iHeight < this.minHeight){var tWidth = this.RepairScaleWidth(this.minHeight);if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; }}}else{iHeight = this.RepairHeight(iHeight, mxHeight);}this._styleWidth = iWidth;this._styleHeight = iHeight; }, //top RepairTop: function() {this._styleTop = this._fixTop - this._styleHeight; }, //left RepairLeft: function() {this._styleLeft = this._fixLeft - this._styleWidth; }, //height RepairHeight: function(iHeight, mxHeight) {iHeight = Math.min(this.Max ? mxHeight : iHeight, iHeight);iHeight = Math.max(this.Min ? this.minHeight : iHeight, iHeight, 0);return iHeight; }, //width RepairWidth: function(iWidth, mxWidth) {iWidth = Math.min(this.Max ? mxWidth : iWidth, iWidth);iWidth = Math.max(this.Min ? this.minWidth : iWidth, iWidth, 0);return iWidth; }, //比例高度 RepairScaleHeight: function(iWidth) {return Math.max(Math.round((iWidth + this._borderX) / this.Ratio - this._borderY), 0); }, //比例宽度 RepairScaleWidth: function(iHeight) {return Math.max(Math.round((iHeight + this._borderY) * this.Ratio - this._borderX), 0); }, //转向程序 //转右 TurnRight: function(fun) {if(!(this.Min || this._styleWidth)){this._fun = fun;this._sideLeft = this._sideRight;this.Max && this._mxSet();return true;} }, //转左 TurnLeft: function(fun) {if(!(this.Min || this._styleWidth)){this._fun = fun;this._sideRight = this._sideLeft;this._fixLeft = this._styleLeft;this.Max && this._mxSet();return true;} }, //转上 TurnUp: function(fun) {if(!(this.Min || this._styleHeight)){this._fun = fun;this._sideDown = this._sideUp;this._fixTop = this._styleTop;this.Max && this._mxSet();return true;} }, //转下 TurnDown: function(fun) {if(!(this.Min || this._styleHeight)){this._fun = fun;this._sideUp = this._sideDown;this.Max && this._mxSet();return true;} }, //停止缩放 Stop: function() {removeEventHandler(document, "mousemove", this._fR);removeEventHandler(document, "mouseup", this._fS);if(isIE){removeEventHandler(this._obj, "losecapture", this._fS);this._obj.releaseCapture();}else{removeEventHandler(window, "blur", this._fS);} }};</script><style type="text/css">#rRightDown,#rLeftDown,#rLeftUp,#rRightUp,#rRight,#rLeft,#rUp,#rDown{position:absolute;background:#C00;width:7px;height:7px;z-index:5;font-size:0;}#rLeftDown,#rRightUp{cursor:ne-resize;}#rRightDown,#rLeftUp{cursor:nw-resize;}#rRight,#rLeft{cursor:e-resize;}#rUp,#rDown{cursor:n-resize;}#rLeftDown{left:-4px;bottom:-4px;}#rRightUp{right:-4px;top:-4px;}#rRightDown{right:-4px;bottom:-4px;background-color:#00F;}#rLeftUp{left:-4px;top:-4px;}#rRight{right:-4px;top:50%;margin-top:-4px;}#rLeft{left:-4px;top:50%;margin-top:-4px;}#rUp{top:-4px;left:50%;margin-left:-4px;}#rDown{bottom:-4px;left:50%;margin-left:-4px;}#bgDiv{width:600px; height:300px; border:10px solid #666666; position:relative;}#dragDiv{border:1px solid #000000; width:100px; height:60px; top:50px; left:50px; background:#fff;}</style><div id="bgDiv"> <div id="dragDiv"> <div id="rRightDown"> </div> <div id="rLeftDown"> </div> <div id="rRightUp"> </div> <div id="rLeftUp"> </div> <div id="rRight"> </div> <div id="rLeft"> </div> <div id="rUp"> </div> <div id="rDown"></div> </div></div><input id="idScale" type="button" value="设置比例" /><input id="idMin" type="button" value="设置最小范围" /><script>var rs = new Resize("dragDiv", { Max: true, mxContainer: "bgDiv" });rs.Set("rRightDown", "right-down");rs.Set("rLeftDown", "left-down");rs.Set("rRightUp", "right-up");rs.Set("rLeftUp", "left-up");rs.Set("rRight", "right");rs.Set("rLeft", "left");rs.Set("rUp", "up");rs.Set("rDown", "down");$("idScale").onclick = function(){if(rs.Scale){this.value = "设置比例";rs.Scale = false;}else{this.value = "取消比例";rs.Ratio = 0;rs.Scale = true;}}$("idMin").onclick = function(){if(rs.Min){this.value = "设置最小范围";rs.Min = false;}else{this.value = "取消最小范围";rs.Min = true;}}</script></body></html>
希望本文所述对大家的javascript程序设计有所帮助。