JavaScript實(shí)現(xiàn)選擇框按比例拖拉縮放的方法
本文實(shí)例講述了JavaScript實(shí)現(xiàn)選擇框按比例拖拉縮放的方法。分享給大家供大家參考。具體如下:
這里通過(guò)javascript實(shí)現(xiàn)可以像PS一樣拉出一個(gè)選擇框的效果。里面的很多方法都是我們值得學(xué)習(xí)的。
運(yùn)行效果如下圖所示:

具體代碼如下:
<!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 = {
//縮放對(duì)象
initialize: function(obj, options) {
this._obj = $(obj);//縮放對(duì)象
this._styleWidth = this._styleHeight = this._styleLeft = this._styleTop = 0;//樣式參數(shù)
this._sideRight = this._sideDown = this._sideLeft = this._sideUp = 0;//坐標(biāo)參數(shù)
this._fixLeft = this._fixTop = 0;//定位參數(shù)
this._scaleLeft = this._scaleTop = 0;//定位坐標(biāo)
this._mxSet = function(){};//范圍設(shè)置程序
this._mxRightWidth = this._mxDownHeight = this._mxUpHeight = this._mxLeftWidth = 0;//范圍參數(shù)
this._mxScaleWidth = this._mxScaleHeight = 0;//比例范圍參數(shù)
this._fun = function(){};//縮放執(zhí)行程序
//獲取邊框?qū)挾?
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);
//事件對(duì)象(用于綁定移除事件)
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");
},
//設(shè)置默認(rèn)屬性
SetOptions: function(options) {
this.options = {//默認(rèn)值
Max: false,//是否設(shè)置范圍限制(為true時(shí)下面mx參數(shù)有用)
mxContainer:"",//指定限制在容器內(nèi)
mxLeft: 0,//左邊限制
mxRight: 9999,//右邊限制
mxTop: 0,//上邊限制
mxBottom: 9999,//下邊限制
Min: false,//是否最小寬高限制(為true時(shí)下面min參數(shù)有用)
minWidth: 50,//最小寬度
minHeight: 50,//最小高度
Scale: false,//是否按比例縮放
Ratio: 0,//縮放比例(寬/高)
onResize: function(){}//縮放時(shí)執(zhí)行
};
Extend(this.options, options || {});
},
//設(shè)置觸發(fā)對(duì)象
Set: function(resize, side) {
var resize = $(resize), fun;
if(!resize) return;
//根據(jù)方向設(shè)置
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;
};
//設(shè)置觸發(fā)對(duì)象
addEventHandler(resize, "mousedown", BindAsEventListener(this, this.Start, fun));
},
//準(zhǔn)備縮放
Start: function(e, fun, touch) {
//防止冒泡(跟拖放配合時(shí)設(shè)置)
e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
//設(shè)置執(zhí)行程序
this._fun = fun;
//樣式參數(shù)值
this._styleWidth = this._obj.clientWidth;
this._styleHeight = this._obj.clientHeight;
this._styleLeft = this._obj.offsetLeft;
this._styleTop = this._obj.offsetTop;
//四條邊定位坐標(biāo)
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定位參數(shù)
this._fixLeft = this._styleLeft + this._styleWidth;
this._fixTop = this._styleTop + this._styleHeight;
//縮放比例
if(this.Scale){
//設(shè)置比例
this.Ratio = Math.max(this.Ratio, 0) || this._styleWidth / this._styleHeight;
//left和top的定位坐標(biāo)
this._scaleLeft = this._styleLeft + this._styleWidth / 2;
this._scaleTop = this._styleTop + this._styleHeight / 2;
};
//范圍限制
if(this.Max){
//設(shè)置范圍參數(shù)
var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
//如果設(shè)置了容器,再修正范圍參數(shù)
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);
};
//根據(jù)最小值再修正
mxRight = Math.max(mxRight, mxLeft + (this.Min ? this.minWidth : 0) + this._borderX);
mxBottom = Math.max(mxBottom, mxTop + (this.Min ? this.minHeight : 0) + this._borderY);
//由于轉(zhuǎn)向時(shí)要重新設(shè)置所以寫成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時(shí)縮放 mouseup時(shí)停止
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();
//執(zhí)行縮放程序
this._fun(e);
//設(shè)置樣式,變量必須大于等于0否則ie出錯(cuò)
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;
},
//對(duì)角方向
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);
},
//轉(zhuǎn)向程序
//轉(zhuǎn)右
TurnRight: function(fun) {
if(!(this.Min || this._styleWidth)){
this._fun = fun;
this._sideLeft = this._sideRight;
this.Max && this._mxSet();
return true;
}
},
//轉(zhuǎn)左
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;
}
},
//轉(zhuǎn)上
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;
}
},
//轉(zhuǎn)下
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="設(shè)置比例" />
<input id="idMin" type="button" value="設(shè)置最小范圍" />
<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 = "設(shè)置比例";
rs.Scale = false;
}else{
this.value = "取消比例";
rs.Ratio = 0;
rs.Scale = true;
}
}
$("idMin").onclick = function(){
if(rs.Min){
this.value = "設(shè)置最小范圍";
rs.Min = false;
}else{
this.value = "取消最小范圍";
rs.Min = true;
}
}
</script>
</body>
</html>
希望本文所述對(duì)大家的javascript程序設(shè)計(jì)有所幫助。
相關(guān)文章
bootstrap daterangepicker雙日歷時(shí)間段選擇控件詳解
這篇文章主要為大家詳細(xì)介紹了bootstrap daterangepicker雙日歷時(shí)間段選擇控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
JavaScript實(shí)現(xiàn)單擊網(wǎng)頁(yè)任意位置打開新窗口與關(guān)閉窗口的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)單擊網(wǎng)頁(yè)任意位置打開新窗口與關(guān)閉窗口的方法,涉及javascript窗口的相關(guān)操作函數(shù)與使用技巧,需要的朋友可以參考下2017-09-09
JavaScript中in和hasOwnProperty區(qū)別詳解
in操作符只要通過(guò)對(duì)象能訪問(wèn)到屬性就返回true。hasOwnProperty()只在屬性存在于實(shí)例中時(shí)才返回true。下面通過(guò)本文給大家分享JavaScript中in和hasOwnProperty區(qū)別詳解,感興趣的朋友一起看看吧2017-08-08
JS常用正則表達(dá)式總結(jié)【經(jīng)典】
這篇文章主要介紹了JS常用正則表達(dá)式,總結(jié)分析了常見的數(shù)字、字符、郵箱、身份證、電話等的正則驗(yàn)證技巧,需要的朋友可以參考下2017-05-05
js使用對(duì)象直接量創(chuàng)建對(duì)象的代碼
js使用對(duì)象直接量創(chuàng)建對(duì)象的代碼...2007-09-09

