javascript 拖拉缩放效果
拖拉缩放效果,实现通过鼠标拖动来调整层的面积(宽高)大小。例如选框效果。
这里的拖拉缩放比一般的选框复杂一点,能设置八个方位(方向)的固定触发点,能设置最小范围,最大范围和比例缩放。
跟拖放效果一样,程序的原型也是在做图片切割效果的时候做出来的。但这个效果的参考少的多,基本上靠自己摸索,走了不少弯路,现在总算把自己想要的效果做出来了,程序跟上一个版本比较也已经“面目全非”,还是觉得有很多需要改进的地方,就像永远没有最完美的土耳其地毯。
这里也有一个简化版的simpleresize,方便学习。
效果预览
程序说明
其中用到的鼠标捕获、清除选择等,在拖放效果中有说明的这里就略过。下面以simpleresize为例说一下基本原理。
【程序原理】
程序需要用set来添加触发对象(就是用来拖拉的对象,详细看使用说明),主要是设置mousedown事件来触发start程序开始缩放。
start程序主要用来设置缩放程序_fun和缩放需要的参数,最后设置mousemove事件触发resize程序进行缩放,mouseup事件中执行取消缩放stop程序。
resize程序的任务是执行缩放程序_fun和设置整理后的样式,这里为了简化程序样式是全部一起设置的,这样程序的注意流程就完成了。
ps:设置样式的值必须是大于0的数,否则ie会报错。
下面说说缩放的原理,先以右边拖拉为例,右边拖拉一般是以左边为固定点,右边进行缩放。
首先记录左边定位参数_sideleft:
this._sideleft = e.clientx - this._stylewidth;
在拖拉时,就可以根据这个参照值计算拖拉后要设置的样式参数_stylewidth:
this._stylewidth = math.max(e.clientx - this._sideleft, 0);
上面的程序能保证样式是大于等于0的数。
至于左边就麻烦一点,因为左边拖拉是以右边为固定点,这就必须在设置宽度的同时设置left才能,保证右边固定。
首先记录右边定位参数_sideright:
this._sideright = e.clientx + this._stylewidth;
还有left的定位参数_fixleft:
this._fixleft = this._stylewidth + this._styleleft;
在拖拉时,计算_stylewidth:
this._stylewidth = math.max(this._sideright - e.clientx, 0);
在根据_stylewidth设置_styleleft:
this._styleleft = this._fixleft - this._stylewidth;
上下同理,至于斜角的四个方向只是同时执行两个方向,例如右下就是同时执行右边和下边:
this.right(e); this.down(e);
【程序结构】
在更详细的程序说明之前,先了解一下程序结构。
当点击触发点,就会根据设置给缩放程序_fun设置为八个方向的缩放程序的其中一个。
八个缩放程序分别是:up(上)、down(下)、right(右)、left(左)、rightdown(右下)、rightup(右上)、leftdown(左下)和leftup(左上)。
在这些缩放程序,首先会进行宽和高的设置,由于宽和高的设置还需要经过范围限制和比例缩放的修正,而这些会在修正程序中处理。
修正程序包括几个部分:
repairx:水平方向修正(左右方向);
repairy:垂直方向修正(上下方向);
repairangle:对角方向修正(右下、右上、左下、左上);
repairtop:top修正(用于以右边为固定点定位);
repairleft:left修正(用于以下边为固定点定位);
repairheight:高度修正;
repairwidth:宽度修正。
如果没有设置最小范围限制,当缩放超过定位边时就会自动转向,例如右边缩放,左边定位,当拖动到左边定位的左边时,就会切换成左边缩放,右边定位,而这个切换是在转向程序中进行的。
转向程序包括几个部分:
turnright:右转程序;
turnleft:左转程序;
turnup:上转程序;
turndown:下转程序。
基本结构了解后,下面就开始介绍程序细节。
【最小范围限制】
最小范围限制就是限制缩放的宽和高,程序中把min设为true,就可以通过minwidth和minheight属性进行限制。
单是限制很简单,只要超过限制就把值设成限制值就行了,这个主要是在修正程序repairheight和repairwidth中修正:
例如repairwidth中:
iwidth = math.max(this.min ? this.minwidth : iwidth, iwidth, 0);
注意这里带了个0,保证最小值大于等于0。
【最大范围限制】
最大范围限制,复杂一点,是固定一个(矩形)范围,然后把缩放限制在范围内。
这个范围限制跟拖放效果的类似,有四个范围属性:上(mxtop)、下(mxbottom)、左(mxleft)、右(mxright)。
程序中把max设为true就可以设置。
然后根据这四个范围属性设置四个范围参数,_mxrightwidth、_mxdownheight、_mxupheight和_mxleftwidth。
这四个围参数代表的是相对于定位边的最大宽度或高度,例如_mxrightwidth就是当右边缩放时(左边固定),宽度可以设置的最大值:
this._mxrightwidth = math.max(mxright - this._styleleft - this._borderx, this.min ? this.minwidth : 0);
这里要小心的是不要把边框忽略了。
然后在right缩放程序中,把这个参数传递给repairx,而repairx把参数传递给repairwidth并在里面修正宽度:
iwidth = math.min(this.max ? mxwidth : iwidth, iwidth);
还有容器范围限制,这个跟拖放效果的差不多,这里就不重复了。此外在start程序中还会对异常的范围参数进行修正,不过这里考虑的不多,估计并不很完善,最好还是不要设一些奇怪的参数。
【比例缩放】
比例缩放就是缩放的时候同时设置宽和高,使用宽和高按照一定的比例显示。
程序中把scale设为true就可以启用,并且ratio可以设置比例大小(宽/高),如果不设置的话就会自动取当前的宽/高比例。
对于对角方向,在比例缩放的情况下宽和高就不能同时设置,而必须有一个优先另一个参照比例设置了。
这个要注意,否则很容易进入死胡同。repairangle修正程序中就是宽度优先的,高度再按比例修正(参考代码)。
而左右上下四个方向,是以缩放对象对称轴为中心缩放的。
以左右方向为例,要实现这个效果,首先在start程序中设置中心定位坐标_scaletop:
this._scaletop = this._styletop + this._styleheight / 2;
当修正好高之后,再用这个坐标设置_styletop值:
this._styletop = this._scaletop - iheight / 2;
其实就是设置高之后再修正top,使缩放之后的缩放对象中心的水平坐标保持不变,就做出以缩放对象的水平对称轴为中心的缩放了。
还有两个比例设置程序repairscaleheight和repairscalewidth,在这两个程序分别按比例设置高和宽。
这里必须留意一个问题,程序在计算样式参数的时候,是不计算边框的,但比例计算时应该把边框算进去。
例如repairscaleheight程序中:
return math.max(math.round((iwidth + this._borderx) / this.ratio - this._bordery), 0);
注意,因为这样计算的结果可能会小于0,所以用math.max保证结果大于0(上面已经说了样式值必须大于0)。
【范围限制下的比例缩放】
一般的比例缩放很简单,在宽或高取值之后,按比例设置另一个值就行了。
但如果有了范围限制有可能按比例缩放后,就超过范围限制了。
如果只考虑最大范围限制的话,可以再修正,每次修正的范围会越来越小,没有问题。
但加上最小范围限制,就可能这边已经到了最小范围了,但另一边还在最大范围限制之外了。
这个时候就必须小心细心处理了,当两个范围限制发生冲突时,要放弃其中一个,程序中是优先考虑最大范围限制,放弃最小范围限制,这个看起来没什么但如果思想转不过来,就很容易钻入死胡同去了(经验教训t_t)。
例如用宽度和repairscaleheight程序已经获得了高的值iheight,可以这样设置宽和高:
code
if(this.max && iheight > this._mxscaleheight){
iheight = this._mxscaleheight;
iwidth = this.repairscalewidth(iheight);
}else if(this.min && iheightthis.minheight){
var twidth = this.repairscalewidth(this.minheight);
if(twidthmxwidth){ iheight = this.minheight; iwidth = twidth; }
}
说明一下这段代码:
首先判断iheight是否超过最大值,是的话就根据最大值设置宽和高,由于优先考虑最大范围所以宽是否超过最小范围就不用再考虑了;
如果没有超过最大值,再判断是否小于最小值,是的话用高度最小值和repairscalewidth程序取要设置的宽赋给一个临时变量twidth,然后判断twidth是否超过最大范围,不是的话就可以进行赋值,否则就放弃修改。
【自动转向】
如果没有设置最小范围限制,当超过改方向能设置宽高的范围就会自动转向。
转向程序中需要一个参数表示转向后要执行的缩放程序,并重新设置几个属性。
以左转程序turnleft为例:
_fun:设置为转向后要执行的缩放程序;
_siderigh:设置为当前的_sideleft,即以把右边定位左边设置成原来的左边定位坐标(形象点说就是原来是左边不动,改成右边不动);
_fixleft:左转后的定位需要_fixleft,设置为_styleleft,本来是left加width的,由于左转时width是0,所以只要left就够了。
如果设置了最大范围限制,还需要设置一下范围参数,为了方便,程序使用了一个_mxset方法重新设置范围参数。
程序如下:
code
if(!(this.min || this._stylewidth)){
this._fun = fun;
this._sideright = this._sideleft;
this._fixleft = this._styleleft;
this.max && this._mxset();
return true;
}
如果发生了转向就返回true,这个主要是用在对角方向的转向。
对于对角方向,可能会转向两个方向,但同一时间最多只能设置一个转向(同时转两个可能会造成混乱),
而且在按比例缩放时,程序规定只进行水平方向的转向(比例缩放中已说明)。
例如对于rightdown转向,可以这样满足这两个需求:
this.turnleft(this.leftdown) || this.scale || this.turnup(this.rightup);
【样式修正】
由于offset获取的值跟style设置的值并不是一样的,例如offsetwidth包括padding、border和width。
所以在获取和设置时必须做一些修正,例如用offsetwidth获取宽度,要设置width时必须减去padding和border等等。
程序中有_borderx和_bordery属性分别是缩放对象的左右和上下边框宽度:
code
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);
程序中主要是修正了border,对于padding、margin都没有考虑,如果设置了这些属性的要注意一下哦。
【样式设置】
首先缩放对象必须是绝对定位,如果有范围限制容器就必须把容器设置成相对定位:
code
this._obj.style.position = "absolute";
!this._mxcontainer || currentstyle(this._mxcontainer).position == "relative" || (this._mxcontainer.style.position = "relative");
推荐根据拖拉的方向设置拖拉对象的鼠标样式,其中右下和左上是nw-resize,左下和右上是ne-resize,上和下是n-resize,左和右是e-resiz。
至于拖拉对象的定位就有技巧一点,绝对定位到四个角比较简单,适当设置top,left,right和height到为0就行了,例如右上角是right和top为0。
四个边就难一点,参考这里的居中显示效果,利用定位样式和margin就能做到居中了。
例如右边设置top为50%,margin-top为高度的负的一半就能在右边上下居中了。
程序说明就到这里了,还有一些结构上的东西以我的能力还是比较难写出来,还是看代码来领会吧。
程序有很多相似的结构,总感觉可以整理得更好,等以后自己的编写水平高点的时候再来看拉。
使用说明
首先实例化一个拖拉缩放对象:
var rs = new resize("dragdiv");
有以下这些可选参数和属性:
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(){}//缩放时执行
然后使用set程序添加拖拉对象,set程序需要两个参数,第一格是拖拉对象,第二个是缩放参数。
其中缩放参数可以是"right-down"、"left-down"、"right-up"、"left-up"、"right"、"left"、"up"和"down"其中之一。
像这样添加就行了:
rs.set("rdown", "down");
ps:如果跟跟拖放效果配合使用时,要禁止冒泡,否则一点拖拉对象就冒泡到拖放了。
程序代码
code
//缩放程序
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 && iheightthis.minheight){
var twidth = this.repairscalewidth(this.minheight);
if(twidthmxwidth){ 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 && iwidththis.minwidth){
var theight = this.repairscaleheight(this.minwidth);
if(theightmxheight){ 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 && iheightthis.minheight){
var twidth = this.repairscalewidth(this.minheight);
if(twidthmxwidth){ 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);
}
}
};
ps:实例中包含了拖放效果,不过两个效果是完全独立的,删掉拖放的部分也能正常缩放。
转载请注明出处:http://www.cnblogs.com/cloudgamer/
如有任何建议或疑问,欢迎留言讨论。
如果觉得文章不错的话,欢迎点一下右下角的推荐。
程序中包含的js工具库cjl.0.1.min.js,原文在这里。
标签: javascript, 缩放, resize, 范围限制, 选框, 拖拉, 比例, 转向
绿色通道:好文要顶关注我收藏该文与我联系
posted @ 2008-12-03 09:07 cloudgamer 阅读(34372) 评论(77)编辑 收藏
发表评论
2191655
回复 引用 查看
#1楼 2008-12-03 09:13 iimax
js高手,学习
回复 引用
#2楼 2008-12-03 09:15 过路人[未注册用户]
有意思:)
回复 引用 查看
#3楼 2008-12-03 09:25 随风逝去(叶进)
收下了
回复 引用
#4楼 2008-12-03 09:42 zzzzz[未注册用户]
这个效果使用jquery可以很简单的就实现了。 :)
回复 引用
#5楼 2008-12-03 09:42 至强1[未注册用户]
真是不错..
但你那个"图片切割"能不能让底图也能调整呀..这个才能真正切出缩略图.
回复 引用 查看
#6楼 2008-12-03 09:56 kenblove
demo做的很帅~
回复 引用
#7楼 2008-12-03 10:08 nonew[未注册用户]
extjs里有现成的方法~~
回复 引用 查看
#8楼[楼主] 2008-12-03 10:18 cloudgamer
@iimax
@过路人
@随风逝去(叶进)
@zzzzz
@至强1
@kenblove
@nonew
谢谢各位支持
框架当然能做出来
但如果没有这些原理
写框架的人能做的出来吗?
框架只是一个工具,这里我是给大家js的知识原理而不是教大家使用工具
回复 引用 查看
#9楼 2008-12-03 10:26 阿一(杨正祎)
--引用--------------------------------------------------
nonew: extjs里有现成的方法~~
--------------------------------------------------------
使用框架,用于受制于人。
用于只能模仿,不能超越。不利于自己技术的提高。
回复 引用
#10楼 2008-12-03 10:27 sherrytop[未注册用户]
thanks for sharing!
回复 引用
#11楼 2008-12-03 10:38 chenjun[未注册用户]
提个建议,控件在获取焦点的时候应该现在拖拽边框,失去焦点时,应该去掉!
回复 引用 查看
#12楼 2008-12-03 10:41 baozi
谢谢分享
回复 引用 查看
#13楼 2008-12-03 10:43 mythysjh
顶楼主,佩服的五体投地!
回复 引用 查看
#14楼[楼主] 2008-12-03 10:44 cloudgamer
@阿一(杨正祎)
@mythysjh
@sherrytop
@chenjun
@baozi
谢谢支持
chenjun这个属于扩展内容
跟拖拉缩放本身没什么关系的
而且也不难可以自己动手试试
回复 引用 查看
#15楼 2008-12-03 13:12 net1234
谢谢分享,楼主很厉害
回复 引用
#16楼 2008-12-03 13:56 eric pan1987[未注册用户]
this demo is so nice. thank your for your sharing!
回复 引用
#17楼 2008-12-03 15:37 吃请客[未注册用户]
不错的东西,已经收录了、
http://www.scriptlover.com/controls/?url=/controls/resize
回复 引用
#18楼 2008-12-03 16:07 nonew[未注册用户]
--引用--------------------------------------------------
bravo yang: 有一个小问题,在空白区域mousedown然后随机移动鼠标会出现蓝色背景.是lz有意而为之么?
--------------------------------------------------------
晕 ~那是选择 类似 ctrl+a
回复 引用 查看
#19楼[楼主] 2008-12-03 16:42 cloudgamer
@net1234
@eric pan1987
@吃请客
@bravo yang
@nonew
谢谢支持
回复 引用 查看
#20楼 2008-12-03 18:35 works guo
很帅哦
回复 引用 查看
#21楼 2008-12-03 18:50 airwolf2026
支持楼主的奉献精神.另外bs那些说框架可以做出来的人.嘎嘎
回复 引用 查看
#22楼[楼主] 2008-12-03 19:18 cloudgamer
@airwolf2026
@works guo
@bravo yang
谢谢支持
一起学习
回复 引用 查看
#23楼 2008-12-03 21:07 菜菜渣囧
授人以渔的lz,顶一个~
回复 引用 查看
#24楼 2008-12-03 21:21 diryboy
收藏学习了。
对了,我也是顺德人,顺便问下,楼主是在顺德工作吗?
回复 引用
#25楼 2008-12-03 21:39 myhanbaobao[未注册用户]
学习中。。。。心服、口服、佩服。。。。。兄长请受小妹一拜
回复 引用 查看
#26楼 2008-12-04 09:10 小宇儿
好东西,一定要顶
回复 引用 查看
#27楼[楼主] 2008-12-04 11:17 cloudgamer
@菜菜渣囧
@myhanbaobao
@小宇儿
谢谢支持
@diryboy
我是在顺德工作哦
呵呵
回复 引用
#28楼 2008-12-04 11:19 papa[未注册用户]
不能不顶了~
回复 引用
#29楼 2008-12-05 00:45 garyw[未注册用户]
可以考虑加个handle,就像window的窗口一样. thans.
回复 引用 查看
#30楼[楼主] 2008-12-05 01:11 cloudgamer
@papa
谢谢支持
@garyw
你说的跟这个效果关系不大
你可以自己试试
回复 引用 查看
#31楼 2008-12-05 09:09 四喜
太强悍了,学习下。
回复 引用 查看
#32楼 2008-12-08 14:02 寒@鹏
8错 不过好像没什么实用价值 就在 交友网站看见过此类效果
不知道还能用哪里 o(∩_∩)o哈哈~ 不过还是高手楼主
回复 引用 查看
#33楼[楼主] 2008-12-08 14:39 cloudgamer
@四喜
谢谢支持
@寒@鹏
价值还是有的
有很多模拟弹出窗口的拖拉控制窗口大小就可以用到
回复 引用
#34楼 2008-12-09 16:50 小a不a点a[未注册用户]
高人请帮我看看这个问题
http://zhidao.baidu.com/question/78447819.html
回复 引用
#35楼 2008-12-14 22:14 oatn[未注册用户]
高人,吐血佩服中!
回复 引用 查看
#36楼 2008-12-15 07:28 xland
顶
回复 引用
#37楼 2008-12-16 13:06 *iron*[未注册用户]
博主真乃神人也!!!!
回复 引用 查看
#38楼 2008-12-31 12:23 damon king
楼主说的没错,这些都是很好的js学习资料,谢谢楼主的无私分享!
回复 引用 查看
#39楼[楼主] 2009-01-09 14:07 cloudgamer
@小a不a点a
@oatn
@xland
@*iron*
@damon king
谢谢支持
回复 引用
#40楼 2009-01-30 12:45 过路呵呵[未注册用户]
效果还可以,但是不太兼容ff,原因是“没有禁止他元素看见该事件和禁止网页中的默认动作”,因此有楼上的“在空白区域mousedown然后随机移动鼠标会出现蓝色背景”现象。要做些小的修改哦。
回复 引用 查看
#41楼[楼主] 2009-02-01 21:48 cloudgamer
@过路呵呵
那是选择内容而已
回复 引用 查看
#42楼 2009-03-05 12:05 lhgstudio
老大我有个问题,我照你这个试验了一下,如果把控制点改成小图片的话,把小图片做为控制点的背景图片,然后在点击和拖动时在ie6下鼠标的指针都会变成默认的样式,这个怎么解决呢?
回复 引用 查看
#43楼[楼主] 2009-03-05 13:57 cloudgamer
@lhgstudio
是背景图还是直接图片
好像没有那样的问题
最好是给我个页面我看看
回复 引用 查看
#44楼 2009-03-28 12:23 yahoo
太强悍了,
在这里学习比看什么书都要强得多!~
援人以鱼,不如援人以渔,
bs说框能实现的那些人
回复 引用 查看
#45楼 2009-04-30 16:33 四喜
请问楼主,如果我想添加多个可以拖动并缩放的div并且在拖放和改变大小的动作结束的时候,把该div(div已编号)的左上角坐标和高、宽保存到数据库中(js请求webservice这块儿我可以搞定,),该怎么做?
回复 引用 查看
#46楼 2009-04-30 16:34 四喜
能给个思路吗?谢谢。
回复 引用 查看
#47楼[楼主] 2009-04-30 16:43 cloudgamer
@yahoo
谢谢支持
@四喜
//停止缩放
stop
里面执行你那个操作就行了
至于那些相关参数你可以通过this._obj来获取相关属性
回复 引用 查看
#48楼 2009-04-30 16:52 四喜
@cloudgamer
谢谢!
//停止缩放
stop: function() {
removeeventhandler(document, "mousemove", this._fr);
removeeventhandler(document, "mouseup", this._fs);
document.title="已经停止缩放!";
if(isie){
removeeventhandler(this._obj, "losecapture", this._fs);
this._obj.releasecapture();
}else{
removeeventhandler(window, "blur", this._fs);
}
}
我再研究下多个层拖动的问题。再次感谢。
回复 引用
#49楼 2009-05-05 16:08 jiyuanjie[未注册用户]
请问博主,我设置div属性contenteditable = "true",使div中的文本可编辑。但是调用drag.js后可编辑这个功能就失效了,请问怎么解决。
回复 引用 查看
#50楼[楼主] 2009-05-05 16:20 cloudgamer
@jiyuanjie
这个没什么办法
因为要编辑就要点击
这个点击会跟拖动程序冲突
或者你看看怎么处理一下这两个事件的关系咯
回复 引用
#51楼 2009-05-19 15:42 xiongzhijian[未注册用户]
学习了....非常佩服.
回复 引用 查看
#52楼 2009-06-01 11:05 wtcsy
拜读了很久
好东西 up
有些不明白 会何可以想出这样的构造方式
我现在写程序怎么老是直线式写程序
回复 引用 查看
#53楼[楼主] 2009-06-01 11:20 cloudgamer
@wtcsy
你的意思是initialize?
这个我也是参考prototype.js的
@xiongzhijian
谢谢支持
回复 引用 查看
#54楼 2009-06-01 11:30 wtcsy
这个 我没说清楚
我是说计算位置时候的方法 repairx ,repairtop等等之间的关系
是如何想到这么去构造的了一点都不直线
ps:其实计算大小位置的过程 看的也不大懂!~
回复 引用 查看
#55楼[楼主] 2009-06-01 11:37 cloudgamer
@wtcsy
这个其实也不是一下子写出来的
一开始肯定是先实现效果,这时程序代码可能会很混乱
接着才开始整理程序架构,一点一点改进的
回复 引用 查看
#56楼 2009-10-16 10:59 gevilhost
好东西
回复 引用 查看
#57楼 2010-06-25 14:51 李克华
楼主好强大,在这里成长!
回复 引用
#58楼 2010-08-11 08:20 yuffiy[未注册用户]
@cloudgamer
要为一个元素添加拉伸缩放特性,那8个小控制层是不是在mousedown的时候实例化,在mouseup的时候释放掉比较好?
回复 引用 查看
#59楼[楼主] 2010-08-11 08:31 cloudgamer
@李克华
@gevilhost
谢谢支持
回复 引用 查看
#60楼[楼主] 2010-08-11 08:34 cloudgamer
@yuffiy
你也可以试试
回复 引用 查看
#61楼 2010-10-02 20:49 笨蛋的座右铭
我是来找渣的!
这个案例结构性挺强的,感觉不错
回复 引用 查看
#62楼[楼主] 2010-10-02 22:42 cloudgamer
@笨蛋的座右铭
欢迎
回复 引用 查看
#63楼 2010-10-03 09:32 笨蛋的座右铭
记得前两天说的关于&16的问题吗?就是那个位运算的算法,其实上它可以应用到本例,并且将程序提升到另一个高度,因为我觉得你这个程序写得太繁索,就从另一个角度实现了些功能,这里提供一个类似于草稿的示例,楼主体会一下吧:
回复 引用 查看
#65楼 2010-10-03 09:40 笨蛋的座右铭
还要说一下,你原来的offset实现的resize算法,个人觉得其应用场景有限制,灵活性不够
回复 引用 查看
#66楼[楼主] 2010-10-03 10:43 cloudgamer
@笨蛋的座右铭
不错
回复 引用
#67楼 2010-11-03 12:15 helloworld111[未注册用户]
很好,很强大
回复 引用
#68楼 2010-11-29 14:38 刹那永恒[未注册用户]
有bug = =! 鼠标 点住上面一个点,一直向上重复拉动,或者左侧一直拉动。这个剪贴框会无限放大的。- -~
望楼主改进一下
回复 引用 查看
#69楼[楼主] 2010-11-29 15:12 cloudgamer
@helloworld111
谢谢支持
回复 引用 查看
#70楼[楼主] 2010-11-29 15:12 cloudgamer
@刹那永恒
没发现这个问题啊
回复 引用 查看
#71楼 2010-11-29 17:19 陈小媛
没有做过让我失望的~~~偶像啊~~~吧唧!
回复 引用
#72楼 2010-12-20 10:57 lanran[未注册用户]
lz,能不能做一个按钮什么的。一点击就能在框中生成一个可以拖动的div
?
回复 引用 查看
#73楼[楼主] 2010-12-20 14:31 cloudgamer
@陈小媛
谢谢支持
回复 引用 查看
#74楼[楼主] 2010-12-20 14:31 cloudgamer
@lanran
你可以自己扩展
回复 引用 查看
#75楼 2010-12-25 15:09 zouyup
repairtop:top修正(用于以右边为固定点定位);
repairleft:left修正(用于以下边为固定点定位);
后边括号里的内容是不是写反了?
回复 引用 查看
#76楼[楼主] 2010-12-26 20:22 cloudgamer
@zouyup
不记得了
回复 引用 查看
#77楼 2011-09-02 17:16 qiaoliubang
太牛了
发表评论
昵称: [登录]
主页:
邮箱:(仅博主可见)
验证码:看不清。
换一个
评论内容:
记住我的昵称和主页
-->
[使用ctrl+enter键快速提交评论]
0
1346386
7fsnv8a8mqg=
最新it新闻:
» 更多新闻...
最新知识库文章:
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/