摘要:我就不提除此以外還需要實(shí)現(xiàn)的一些業(yè)務(wù)上的細(xì)節(jié)交互了,本篇文章只講講我實(shí)現(xiàn)的拖拽功能的原理。這里其實(shí)大家就可以看出來(lái)了,得益于面向?qū)ο蟮臋C(jī)制,我們可以很簡(jiǎn)單的實(shí)現(xiàn)一些畫(huà)框拖拽功能。
引言
前不久,老大給我分配一個(gè)比較吊炸天的任務(wù)。要我實(shí)現(xiàn):在一張圖片上,可以用鼠標(biāo)畫(huà)框。除此以外,畫(huà)出來(lái)的框,可以實(shí)現(xiàn)resize,也就是說(shuō)可以通過(guò)鼠標(biāo)操作縮放,也可以進(jìn)行拖拽。我就不提除此以外還需要實(shí)現(xiàn)的一些業(yè)務(wù)上的細(xì)節(jié)交互了,本篇文章只講講我實(shí)現(xiàn)的拖拽功能的原理。
初始畫(huà)框?qū)ο?/b>由于也是上的需求,要求不止畫(huà)一個(gè)框,有可能用戶(hù)會(huì)畫(huà)好多框,如果只是簡(jiǎn)單的檢測(cè)鼠標(biāo)事件定位一個(gè)個(gè)框,很容易導(dǎo)致縮放和拖拽功能的紊亂,因此,運(yùn)用面向?qū)ο蟮乃枷耄瑢⑼献Ш涂s放的框變成一個(gè)對(duì)象,其所有其他鼠標(biāo)事件的綁定都在這個(gè)對(duì)象上。
廢話(huà)不多說(shuō),直接上源碼,思路很簡(jiǎn)單。
function newBox(options) { this.container = $(""); this.dragLeft = $(""); this.dragTop = $(""); this.dragRight = $(""); this.dragBottom = $(""); this.dragTopLeft = $(""); this.dragTopRight = $(""); this.dragBottomLeft = $(""); this.dragBottomRight = $(""); this.sureBtn = $(""); this.cancelBtn = $(""); this.enableEdit = true; this.init(); this.options = options; } newBox.prototype = { init: function() { this.container.append(this.dragLeft); this.container.append(this.dragTop); this.container.append(this.dragRight); this.container.append(this.dragBottom); this.container.append(this.dragTopLeft); this.container.append(this.dragTopRight); this.container.append(this.dragBottomLeft); this.container.append(this.dragBottomRight); this.container.append(this.sureBtn); this.container.append(this.cancelBtn); this.container.on({ "mousedown": this.containerMouseDown.bind(this), "click": this.enableEditFunc.bind(this) }); this.dragRight.on("mousedown", this.dragRightMouseDown.bind(this)); this.dragLeft.on("mousedown", this.dragLeftMouseDown.bind(this)); this.dragTop.on("mousedown", this.dragTopMouseDown.bind(this)); this.dragBottom.on("mousedown", this.dragBottomMouseDown.bind(this)); this.dragTopLeft.on("mousedown", this.dragTopLeftMouseDown.bind(this)); this.dragTopRight.on("mousedown", this.dragTopRightMouseDown.bind(this)); this.dragBottomRight.on("mousedown", this.dragBottomRightMouseDown.bind(this)); this.dragBottomLeft.on("mousedown", this.dragBottomLeftMouseDown.bind(this)); this.sureBtn.on("click", this.sureFunc.bind(this)); this.cancelBtn.on("click", this.cancelFunc.bind(this)); }, sureFunc: function() { this.disableEditFunc(); if(this.options.sureFunc) this.options.sureFunc(this.container); return false; }, cancelFunc: function() { this.container.remove(); if(this.options.cancelFunc) this.options.cancelFunc(this.container); }, enableEditFunc: function() { var sureBtn = this.sureBtn; // 設(shè)置正在編輯的框的zindex為最大 this.container.css("z-index","100000000") // 先保存未保存的 $(".new_rect .sureBtn").each(function() { if($(this)[0] == sureBtn[0]){ return; } $(this).is(":visible") && $(this).click() && $(this).mouseleave(); }) this.enableEdit = true; this.container.find(".new_react-dots, .dots").show(); this.sureBtn.show(); this.cancelBtn.show(); }, disableEditFunc: function() { var width=this.container.width(); var height=this.container.height(); var area=parseInt(width*height); this.container.css("z-index",100000000-area); this.enableEdit = false; this.container.find(".new_react-dots, .dots").hide(); this.sureBtn.hide(); this.cancelBtn.hide(); }, setPosition: function(position) { this.container.css(position) }, dragRightMouseDown: function(ev) { if(!this.enableEdit) return false; var rightElem = this.dragRight; var o_x = ev.pageX; var o_width = this.container.width(); var o_right = parseFloat(this.container.css("right")); if(rightElem.setCapture) { rightElem.setCapture(); } $(document).on("mousemove.dragRight", doDragRight.bind(this)); $(document).on("mouseup.dragRight", stopDragRight.bind(this)); return false; function doDragRight(e) { var right = o_right - e.pageX + o_x; if(right < 0) right = 0; if(right > o_width + o_right) right = o_width + o_right this.setPosition({ right: right }); return false; } function stopDragRight(e) { if(rightElem.releaseCapture) { rightElem.releaseCapture(); } $(document).off("mousemove.dragRight"); $(document).off("mouseup.dragRight"); return false; } }, dragLeftMouseDown: function(ev) { if(!this.enableEdit) return false; var leftElem = this.dragLeft; var o_x = ev.pageX; var o_width = this.container.width(); var o_left = parseFloat(this.container.css("left")); if(leftElem.setCapture) { leftElem.setCapture(); } $(document).on("mousemove.dragLeft", doDragLeft.bind(this)); $(document).on("mouseup.dragLeft", stopDragLeft.bind(this)); return false; function doDragLeft(e) { var left = o_left + e.pageX - o_x; if(left < 0) left = 0; if(left > o_width + o_left) left = o_width + o_left this.setPosition({ left: left }); return false; } function stopDragLeft(e) { if(leftElem.releaseCapture) { leftElem.releaseCapture(); } $(document).off("mousemove.dragLeft"); $(document).off("mouseup.dragLeft"); return false; } }, dragTopMouseDown: function(ev) { if(!this.enableEdit) return false; var topElem = this.dragTop; var o_y = ev.pageY; var o_height = this.container.height(); var o_top = parseFloat(this.container.css("top")); if(topElem.setCapture) { topElem.setCapture(); } $(document).on("mousemove.dragTop", doDragTop.bind(this)); $(document).on("mouseup.dragTop", stopDragTop.bind(this)); return false; function doDragTop(e) { var top = o_top + e.pageY - o_y; if(top < 0) top = 0; if(top > o_top + o_height) top = o_top + o_height this.setPosition({ top: top }); return false; } function stopDragTop(e) { if(topElem.releaseCapture) { topElem.releaseCapture(); } $(document).off("mousemove.dragTop"); $(document).off("mouseup.dragTop"); return false; } }, dragBottomMouseDown: function(ev) { if(!this.enableEdit) return false; var bottomElem = this.dragBottom; var o_y = ev.pageY; var o_height = this.container.height(); var o_bottom = parseFloat(this.container.css("bottom")); if(bottomElem.setCapture) { bottomElem.setCapture(); } $(document).on("mousemove.dragBottom", doDragBottom.bind(this)); $(document).on("mouseup.dragBottom", stopDragBottom.bind(this)); return false; function doDragBottom(e) { var bottom = o_bottom - e.pageY + o_y; if(bottom < 0) bottom = 0; if(bottom > o_bottom + o_height) bottom = o_bottom + o_height this.setPosition({ bottom: bottom }); return false; } function stopDragBottom(e) { if(bottomElem.releaseCapture) { bottomElem.releaseCapture(); } $(document).off("mousemove.dragBottom"); $(document).off("mouseup.dragBottom"); return false; } }, dragTopLeftMouseDown: function(ev) { if(!this.enableEdit) return false; var topLeftElem = this.dragTopLeft; var o_y = ev.pageY; var o_x = ev.pageX; var o_height = this.container.height(); var o_width = this.container.width(); var o_top = parseFloat(this.container.css("top")); var o_left = parseFloat(this.container.css("left")); if(topLeftElem.setCapture) { topLeftElem.setCapture(); } $(document).on("mousemove.dragTopLeft", doDragTopLeft.bind(this)); $(document).on("mouseup.dragTopLeft", stopDragTopLeft.bind(this)); return false; function doDragTopLeft(e) { var top = o_top + e.pageY - o_y; var left = o_left + e.pageX - o_x; if(top < 0) top = 0; if(top > o_top + o_height) top = o_top + o_height; if(left < 0) left = 0; if(left > o_width + o_left) left = o_width + o_left; this.setPosition({ top: top, left: left }); return false; } function stopDragTopLeft(e) { if(topLeftElem.releaseCapture) { topLeftElem.releaseCapture(); } $(document).off("mousemove.dragTopLeft"); $(document).off("mouseup.dragTopLeft"); return false; } }, dragTopRightMouseDown: function(ev) { if(!this.enableEdit) return false; var topRightElem = this.dragTopRight; var o_y = ev.pageY; var o_x = ev.pageX; var o_height = this.container.height(); var o_width = this.container.width(); var o_top = parseFloat(this.container.css("top")); var o_right = parseFloat(this.container.css("right")); if(topRightElem.setCapture) { topRightElem.setCapture(); } $(document).on("mousemove.dragTopRight", doDragTopRight.bind(this)); $(document).on("mouseup.dragTopRight", stopDragTopRight.bind(this)); return false; function doDragTopRight(e) { var top = o_top + e.pageY - o_y; var right = o_right - e.pageX + o_x; if(top < 0) top = 0; if(top > o_top + o_height) top = o_top + o_height; if(right < 0) right = 0; if(right > o_width + o_right) right = o_width + o_right; this.setPosition({ top: top, right: right }); return false; } function stopDragTopRight(e) { if(topRightElem.releaseCapture) { topRightElem.releaseCapture(); } $(document).off("mousemove.dragTopRight"); $(document).off("mouseup.dragTopRight"); return false; } }, dragBottomRightMouseDown: function(ev) { if(!this.enableEdit) return false; var bottomRightElem = this.dragBottomRight; var o_y = ev.pageY; var o_x = ev.pageX; var o_height = this.container.height(); var o_width = this.container.width(); var o_bottom = parseFloat(this.container.css("bottom")); var o_right = parseFloat(this.container.css("right")); if(bottomRightElem.setCapture) { bottomRightElem.setCapture(); } $(document).on("mousemove.dragBottomRight", doDragTopRight.bind(this)); $(document).on("mouseup.dragBottomRight", stopDragTopRight.bind(this)); return false; function doDragTopRight(e) { var bottom = o_bottom - e.pageY + o_y; var right = o_right - e.pageX + o_x; if(bottom < 0) bottom = 0; if(bottom > o_bottom + o_height) bottom = o_bottom + o_height; if(right < 0) right = 0; if(right > o_width + o_right) right = o_width + o_right; this.setPosition({ bottom: bottom, right: right }); return false; } function stopDragTopRight(e) { if(bottomRightElem.releaseCapture) { bottomRightElem.releaseCapture(); } $(document).off("mousemove.dragBottomRight"); $(document).off("mouseup.dragBottomRight"); return false; } }, dragBottomLeftMouseDown: function(ev) { if(!this.enableEdit) return false; var bottomLeftElem = this.dragBottomLeft; var o_y = ev.pageY; var o_x = ev.pageX; var o_height = this.container.height(); var o_width = this.container.width(); var o_bottom = parseFloat(this.container.css("bottom")); var o_left = parseFloat(this.container.css("left")); if(bottomLeftElem.setCapture) { bottomLeftElem.setCapture(); } $(document).on("mousemove.dragBottomLeft", doDragTopLeft.bind(this)); $(document).on("mouseup.dragBottomLeft", stopDragTopLeft.bind(this)); return false; function doDragTopLeft(e) { var bottom = o_bottom - e.pageY + o_y; var left = o_left + e.pageX - o_x; if(bottom < 0) bottom = 0; if(bottom > o_bottom + o_height) bottom = o_bottom + o_height; if(left < 0) left = 0; if(left > o_width + o_left) left = o_width + o_left; this.setPosition({ bottom: bottom, left: left }); return false; } function stopDragTopLeft(e) { if(bottomLeftElem.releaseCapture) { bottomLeftElem.releaseCapture(); } $(document).off("mousemove.dragBottomLeft"); $(document).off("mouseup.dragBottomLeft"); return false; } }, containerMouseDown: function(ev) { if(!this.enableEdit) return false; var o_x = ev.pageX; var o_y = ev.pageY; var containerWidth = this.container.width(); var containerHeight = this.container.height(); var o_top = parseFloat(this.container.css("top")); var o_left = parseFloat(this.container.css("left")); var o_right = parseFloat(this.container.css("right")); var o_bottom = parseFloat(this.container.css("bottom")); if(this.container.setCapture) { this.container.setCapture(); } $(document).on("mousemove.container", doDrag.bind(this)); $(document).on("mouseup.container", stopDrag.bind(this)); return false; function doDrag(e) { var disY = e.pageY - o_y; var disX = e.pageX - o_x; var top = o_top + disY; var left = o_left + disX; var right = o_right - disX; var bottom = o_bottom - disY; if(top < 0) { top = 0; bottom = o_bottom + o_top; } if(bottom < 0) { bottom = 0; top = o_top + o_bottom; } if(left < 0) { left = 0; right = o_right + o_left; } if(right < 0) { right = 0; left = o_right + o_left; } this.setPosition({top: top, bottom: bottom, left: left, right: right}); return false; } function stopDrag(ev) { if(this.container.releaseCapture) { this.container.releaseCapture(); } $(document).off("mousemove.container"); $(document).off("mouseup.container"); return false; } } }
至此,一個(gè)支持縮放和拖拽功能的box對(duì)象已經(jīng)創(chuàng)建好了,但是,還沒(méi)有實(shí)現(xiàn)初始畫(huà)框功能,其實(shí)畫(huà)初始框的思路更加簡(jiǎn)單,就是記錄mousedown的時(shí)候鼠標(biāo)地的x,y坐標(biāo)和mouseup時(shí)鼠標(biāo)的x,y坐標(biāo),然后根據(jù)坐標(biāo)值,設(shè)置新建的div的寬度和高度和定位就可以了。下面是源碼,我直接把它做成了jquery插件。
$.fn.draw_drag_test = function(options) { var position = {} var elemWidth, elemHeight, o_x, o_y, d_x, d_y, rect, o_left, o_top; var mouseDown = function(e) { $(this).on({ "mousemove": mouseMove, "mouseup": mouseUp }) var elemLeft = $(this).offset().left, elemTop = $(this).offset().top; elemWidth = $(this).width(); elemHeight = $(this).height(); o_x = e.pageX; o_y = e.pageY; position.left = o_left = o_x - elemLeft; position.top = o_top = o_y - elemTop; rect = new newBox(options); rect.container.css("z-index","100000000"); $(this).append(rect.container); } var mouseMove = function(e) { var m_x = e.pageX, m_y = e.pageY; d_x = m_x - o_x; d_y = m_y - o_y; position.right = elemWidth - position.left - d_x; position.bottom = elemHeight - position.top - d_y; if(d_x < 0) { position.right = elemWidth - o_left; position.left = o_left + d_x; }else { position.left = o_left; } if(d_y < 0) { position.bottom = elemHeight - o_top; position.top = o_top + d_y; }else { position.top = o_top; } rect.setPosition(position); } var mouseUp = function(e) { $(this).off("mouseup", mouseUp); $(this).off("mousemove", mouseMove); $(this).off("mousedown", mouseDown); } return this.each(function() { $(this).off("mousedown").on({ "mousedown": mouseDown }) return this; }) }
這里其實(shí)大家就可以看出來(lái)了,得益于面向?qū)ο蟮臋C(jī)制,我們可以很簡(jiǎn)單的實(shí)現(xiàn)一些畫(huà)框拖拽功能。并且該方法還留了回調(diào)的接口,方便根據(jù)不同的業(yè)務(wù)需求進(jìn)行一些交互操作。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80265.html
摘要:我就不提除此以外還需要實(shí)現(xiàn)的一些業(yè)務(wù)上的細(xì)節(jié)交互了,本篇文章只講講我實(shí)現(xiàn)的拖拽功能的原理。這里其實(shí)大家就可以看出來(lái)了,得益于面向?qū)ο蟮臋C(jī)制,我們可以很簡(jiǎn)單的實(shí)現(xiàn)一些畫(huà)框拖拽功能。 引言 前不久,老大給我分配一個(gè)比較吊炸天的任務(wù)。要我實(shí)現(xiàn):在一張圖片上,可以用鼠標(biāo)畫(huà)框。除此以外,畫(huà)出來(lái)的框,可以實(shí)現(xiàn)resize,也就是說(shuō)可以通過(guò)鼠標(biāo)操作縮放,也可以進(jìn)行拖拽。我就不提除此以外還需要實(shí)現(xiàn)的一...
摘要:我就不提除此以外還需要實(shí)現(xiàn)的一些業(yè)務(wù)上的細(xì)節(jié)交互了,本篇文章只講講我實(shí)現(xiàn)的拖拽功能的原理。這里其實(shí)大家就可以看出來(lái)了,得益于面向?qū)ο蟮臋C(jī)制,我們可以很簡(jiǎn)單的實(shí)現(xiàn)一些畫(huà)框拖拽功能。 引言 前不久,老大給我分配一個(gè)比較吊炸天的任務(wù)。要我實(shí)現(xiàn):在一張圖片上,可以用鼠標(biāo)畫(huà)框。除此以外,畫(huà)出來(lái)的框,可以實(shí)現(xiàn)resize,也就是說(shuō)可以通過(guò)鼠標(biāo)操作縮放,也可以進(jìn)行拖拽。我就不提除此以外還需要實(shí)現(xiàn)的一...
摘要:插件只預(yù)覽該容器下的所有圖片。指定該容器里的圖片點(diǎn)擊預(yù)覽鍵的值就是容器的如果覺(jué)得樣式不滿(mǎn)意什么的,可以直接覆蓋就可以了。預(yù)覽總結(jié)如有疏忽或錯(cuò)誤,希望您及時(shí)指出,我會(huì)盡早修改。有什么需要交流的可在評(píng)論區(qū)與我交流 原生js實(shí)現(xiàn)拖拽縮放預(yù)覽圖片插件 前言 插件功能暫只滿(mǎn)足我司業(yè)務(wù)需求,如果希望有更多的功能,可在下方留言,我盡量擴(kuò)展!如果你有需要或者喜歡的話(huà),可以給我github來(lái)個(gè)star ...
摘要:原文鏈接前端插件庫(kù)站點(diǎn)前端開(kāi)發(fā)文檔博客前端插件庫(kù)前端插件庫(kù)官網(wǎng)是的函數(shù)庫(kù),目的是強(qiáng)化表格操作如搜索排序,并自動(dòng)加入組件引入表格中,使用非常靈活簡(jiǎn)便。由推出,靈活扎實(shí)的建議列表函數(shù)庫(kù)。 原文鏈接:前端插件庫(kù)站點(diǎn):前端開(kāi)發(fā)文檔博客:前端插件庫(kù) 前端插件庫(kù) DataTables 官網(wǎng):https://www.datatables.net/ DataTables是jQuery的JavaScr...
閱讀 2865·2021-10-08 10:12
閱讀 3965·2021-09-22 15:45
閱讀 2555·2019-08-30 15:52
閱讀 2625·2019-08-29 18:44
閱讀 2643·2019-08-29 12:37
閱讀 1153·2019-08-26 13:36
閱讀 2560·2019-08-26 13:34
閱讀 1472·2019-08-26 12:20