JavaScript 拖拉缩放效果

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新闻:

·windows 7官方rss动态主题:《昆虫》

·捡到iphone 4s玩自拍 icloud同步酿悲剧

·铁道部购票网站存泄密危险 cdn服务商技术短板是主因

·利用 mimo magictouch 打造另类的平板电脑

·但愿大嘴巴的消息再次失准

» 更多新闻...

最新知识库文章:

·设计师的品牌意识

·如何成为“10倍效率”开发者

·快速排序(quicksort)的javascript实现

·wcf服务端运行时架构体系详解[续篇]

·wcf服务端运行时架构体系详解[下篇]

» 更多知识库文章...

china-pub 2011秋季教材巡展

china-pub 计算机绝版图书按需印刷服务


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值