200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > div拖拽缩放jquery插件编写——带8个控制点

div拖拽缩放jquery插件编写——带8个控制点

时间:2022-11-11 13:50:13

相关推荐

div拖拽缩放jquery插件编写——带8个控制点

项目中需要对div进行拖拽缩放,需要有控制面板8个控制点的那种,原以为这么常见的效果应该能搜索到很多相关插件,然而可以完成拖拽的实繁,却找不到我想要的,还是自己动手丰衣足食吧

效果预览(只支持pc端)

思路

一、舞台拖拽项定义

拖拽以及缩放需要有一个范围,姑且管这个叫舞台(stage)。另外,在舞台范围内,如何以一种简单的方式定义拖拽项?可以通过给div增加一个拖拽class(例如:resize-item),拖拽项应该是absolute布局,舞台是relative/absolute布局

所以拖拽类需要有如下两个参数

/*** 默认参数*/var defaultOpts = {stage: document, //舞台,默认为stage itemClass: 'resize-item', //可缩放的类名 }; /** * 定义类 */ var ZResize = function(options) { this.options = $.extend({}, defaultOpts, options); this.init(); }

二、生成控制面板

控制面板 面板:为了尽可能少的影响到拖拽项,就不直接在拖拽项上生成控制点,而是为拖拽项增加一个半透明层作为控制面板,控制面板尺寸位置和拖拽项一致,将控制面板插入拖拽项(由于都是absolute布局,不影响原内容),可以更好的控制位置和一一对应

var width = $(this).width();var height = $(this).height(); var resizePanel = $('<div class"resize-panel"></div>'); resizePanel.css({ width: width, height: height, top: 0, left: 0, position: 'absolute', 'background-color': 'rgba(0,0,0,0.5)', cursor: 'move', display: 'none' }); self.appendHandler(resizePanel, $(this));

控制点:为控制面板增加东、南、西、北、东北、西北、西南、东南控制点,为每个控制点设置对应的cursor

'cursor': 'n-resize' //北'cursor': 's-resize' //南 'cursor': 'e-resize' //东 'cursor': 'w-resize' //西 'cursor': 'ne-resize' //东北 'cursor': 'nw-resize' //西北 'cursor': 'se-resize' //东南 'cursor': 'sw-resize' //西南

三、缩放

每个控制点影响的属性不一样

北(上):高度(height) 位置y(拖拽上边,应该保持下边固定,所以高度变化之后位置也要变化)南(下):高度(height)东(右):宽度(width)西(左):宽度(width)位置x(拖拽左边,应该保持右边固定,所以宽度变化之后位置也要变化)东北、西北、东南、西南 以上两两结合

监听控制点mousedown,分别定义一个标志,并且记录下原始位置,如:

//西var wmove = false;el.on('mousedown','.w', function(e) { ox = e.pageX;//原始x位置 ow = el.width(); oleft = parseInt(org.css('left').replace('px', '')); wmove = true; });

监听控制面板的mousedown,同样定义一个标志,用于拖动(drag)监听舞台(stage)的mousemove(注意这里不是监听控制点的mousemove,因为控制点实在是太小,无法灵敏的拖动),判断各个控制点以及控制面板mousedown的标志分别对宽高和位置进行处理。处理的逻辑为:touchmove过程中的e.pageX/e.pageY - ox/oy(原始) = 偏移量,对于第一点中提到的每个控制点影响的属性,根据偏移量进行变化 监听 监听舞台(stage)的mouseup事件(这里同样不能是控制点的mouseup),把所有的mousedown标志重置为false

pc端的mouse事件不同于手机端的touch事件,touchstart->touchmove->touchend触发有顺序性,mouse事件没有顺序性,未触发mousedown也能触发mousemove,所以需要设置标志来判断

四、控制面板的出现隐藏

控制面板初始化的时候,应该是隐藏的,只有点击对应的拖拽项的时候才出现,并且点击舞台空白部分,需要隐藏控制面板(组织事件冒泡)

/**+ 点击item显示拖拽面板*/bindTrigger: function(el) { var self = this; el.on('click', function(e) { //组织事件冒泡,不然会被舞台触发,舞台触发会把控制面板隐藏掉 e.stopPropagation(); self.triggerResize(el); }); }, /** + 点击舞台空闲区域 隐藏缩放面板 */ bindHidePanel: function(el) { var stage = this.options.stage; var itemClass = this.options.itemClass; $(stage).bind('click', function() { $('.' + itemClass).children('div').css({ display: 'none' }); }) }

备注: 相应的HTML内容:

<!doctype html><html><head><meta charset="utf-8"><title>jQuery拖拽放大缩小插件idrag</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css">.item1 {width: 405px;height: 291px;cursor: move;position: absolute;top: 30px;left: 30px;background-color: #FFF;border: 1px solid #CCCCCC;-webkit-box-shadow: 10px 10px 25px #ccc;-moz-box-shadow: 10px 10px 25px #ccc;box-shadow: 10px 10px 25px #ccc;}.item2 {width: 200px;height: 100px;cursor: move;position: absolute;top: 400px;left: 100px;background-color: #FFF;border: 1px solid #CCCCCC;-webkit-box-shadow: 10px 10px 25px #ccc;-moz-box-shadow: 10px 10px 25px #ccc;box-shadow: 10px 10px 25px #ccc;line-height: 100px;text-align: center;}body {background-color: #F3F3F3;}</style></head><body><div class="resize-item item1"><img src="images/dog.png" width="100%" height="100%"></div><div class="resize-item item2">你是我的小小狗</div><script src="js/jquery.min.js"></script><script type="text/javascript" src='js/jquery.ZResize.js'></script><script type="text/javascript">new ZResize();</script></body></html>

相应的js插件jquery.ZResize.js为:

(function($) {/*** 默认参数*/var defaultOpts = {stage: document, //舞台itemClass: 'resize-item', //可缩放的类名};/*** 定义类*/var ZResize = function(options) {this.options = $.extend({}, defaultOpts, options);this.init();}ZResize.prototype = {init: function() {this.initResizeBox();},/*** 初始化拖拽item*/initResizeBox: function() {var self = this;$('.' + self.options.itemClass).each(function() {//创建面板var width = $(this).width();var height = $(this).height();var resizePanel = $('<div class"resize-panel"></div>');resizePanel.css({width: width,height: height,top: 0,left: 0,position: 'absolute','background-color': 'rgba(0,0,0,0.5)',cursor: 'move',display: 'none'});self.appendHandler(resizePanel, $(this));/*** 创建控制点*/var n = $('<div class="n"></div>');//北var s = $('<div class="s"></div>');//南var w = $('<div class="w"></div>');//西var e = $('<div class="e"></div>');//东var ne = $('<div class="ne"></div>');//东北var nw = $('<div class="nw"></div>');//西北var se = $('<div class="se"></div>');//东南var sw = $('<div class="sw"></div>');//西南//添加公共样式self.addHandlerCss([n, s, w, e, ne, nw, se, sw]);//添加各自样式n.css({'top': '-4px','margin-left': '-4px','left': '50%','cursor': 'n-resize'});s.css({'bottom': '-4px','margin-left': '-4px','left': '50%','cursor': 's-resize'});e.css({'top': '50%','margin-top': '-4px','right': '-4px','cursor': 'e-resize'});w.css({'top': '50%','margin-top': '-4px','left': '-4px','cursor': 'w-resize'});ne.css({'top': '-4px','right': '-4px','cursor': 'ne-resize'});nw.css({top: '-4px','left': '-4px','cursor': 'nw-resize'});se.css({'bottom': '-4px','right': '-4px','cursor': 'se-resize'});sw.css({'bottom': '-4px','left': '-4px','cursor': 'sw-resize'});// 添加项目self.appendHandler([n, s, w, e, ne, nw, se, sw], resizePanel);//绑定拖拽缩放事件self.bindResizeEvent(resizePanel, $(this));//绑定触发事件self.bindTrigger($(this));});self.bindHidePanel();},//控制点公共样式addHandlerCss: function(els) {for(var i = 0; i < els.length; i++) {el = els[i];el.css({position: 'absolute',width: '8px',height: '8px',background: '#ff6600',margin: '0','border-radius': '2px',border: '1px solid #dd5500',});}},/*** 插入容器*/appendHandler: function(handlers, target) {for(var i = 0; i < handlers.length; i++) {el = handlers[i];target.append(el);}},/*** 显示拖拽面板*/triggerResize: function(el) {var self = this;el.siblings('.' + self.options.itemClass).children('div').css({display: 'none'});el.children('div').css({display: 'block'});},/*** 拖拽事件控制 包含8个缩放点 和一个拖拽位置*/bindResizeEvent: function(el) {var self = this;var ox = 0; //原始事件x位置var oy = 0; //原始事件y位置var ow = 0; //原始宽度var oh = 0; //原始高度var oleft = 0; //原始元素位置var otop = 0;var org = el.parent('div');//东var emove = false;el.on('mousedown','.e', function(e) {ox = e.pageX;//原始x位置ow = el.width();emove = true;});//南var smove = false;el.on('mousedown','.s', function(e) {oy = e.pageY;//原始x位置oh = el.height();smove = true;});//西var wmove = false;el.on('mousedown','.w', function(e) {ox = e.pageX;//原始x位置ow = el.width();wmove = true;oleft = parseInt(org.css('left').replace('px', ''));});//北var nmove = false;el.on('mousedown','.n', function(e) {oy = e.pageY;//原始x位置oh = el.height();nmove = true;otop = parseInt(org.css('top').replace('px', ''));});//东北var nemove = false;el.on('mousedown','.ne', function(e) {ox = e.pageX;//原始x位置oy = e.pageY;ow = el.width();oh = el.height();nemove = true;otop = parseInt(org.css('top').replace('px', ''));});//西北var nwmove = false;el.on('mousedown','.nw', function(e) {ox = e.pageX;//原始x位置oy = e.pageY;ow = el.width();oh = el.height();otop = parseInt(org.css('top').replace('px', ''));oleft = parseInt(org.css('left').replace('px', ''));nwmove = true;});//东南var semove = false;el.on('mousedown','.se', function(e) {ox = e.pageX;//原始x位置oy = e.pageY;ow = el.width();oh = el.height();semove = true;});//西南var swmove = false;el.on('mousedown','.sw', function(e) {ox = e.pageX;//原始x位置oy = e.pageY;ow = el.width();oh = el.height();swmove = true;oleft = parseInt(org.css('left').replace('px', ''));});//拖拽var drag = false;el.on('mousedown', function(e) {ox = e.pageX;//原始x位置oy = e.pageY;otop = parseInt(org.css('top').replace('px', ''));oleft = parseInt(org.css('left').replace('px', ''));drag = true;});$(self.options.stage).on('mousemove', function(e) {if(emove) {var x = (e.pageX - ox);el.css({width: ow + x});org.css({width: ow + x});} else if(smove) {var y = (e.pageY - oy);el.css({height: oh + y});org.css({height: oh + y});} else if(wmove) {var x = (e.pageX - ox);el.css({width: ow - x,// left: oleft + x});org.css({width: ow - x,left: oleft + x});} else if(nmove) {var y = (e.pageY - oy);el.css({height: oh - y,// top: otop + y});org.css({height: oh - y,top: otop + y});} else if(nemove) {var x = e.pageX - ox;var y = e.pageY - oy;el.css({height: oh - y,// top: otop + y,width: ow + x});org.css({height: oh - y,top: otop + y,width: ow + x});} else if(nwmove) {var x = e.pageX - ox;var y = e.pageY - oy;el.css({height: oh - y,// top: otop + y,width: ow - x,// left: oleft + x});org.css({height: oh - y,top: otop + y,width: ow - x,left: oleft + x});} else if(semove) {var x = e.pageX - ox;var y = e.pageY - oy;el.css({width: ow + x,height: oh + y});org.css({width: ow + x,height: oh + y});} else if(swmove) {var x = e.pageX - ox;var y = e.pageY - oy;el.css({width: ow - x,// left: oleft + x,height: oh + y});org.css({width: ow - x,left: oleft + x,height: oh + y});} else if(drag) {var x = e.pageX - ox;var y = e.pageY - oy;org.css({left: oleft + x,top: otop + y});}}).on('mouseup', function(e) {emove = false;smove = false;wmove = false;nmove = false;nemove = false;nwmove = false;swmove = false;semove = false;drag = false;});},/*** 点击item显示拖拽面板*/bindTrigger: function(el) {var self = this;el.on('click', function(e) {e.stopPropagation();self.triggerResize(el);});},/*** 点击舞台空闲区域 隐藏缩放面板*/bindHidePanel: function(el) {var stage = this.options.stage;var itemClass = this.options.itemClass;$(stage).bind('click', function() {$('.' + itemClass).children('div').css({display: 'none'});})}}window.ZResize = ZResize;})(jQuery);

源码链接:/zengwenfu/z-resize

作者:小虫巨蟹

链接:/p/822afede7489

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。