12.手機端如何拖動組件--WEB設計器JQUERY插件講解(含源碼)
關鍵字:設計器源代碼,Web設計器,工作流設計器,jQuery插件,組態設計器,SCADA系統設計器,流程圖設計,表單設計建模,報表設計,可視化,設計時,運行時,輕量級開放平臺。
前面示例都只是展示在桌面瀏覽器顯示,當用手機瀏覽器打開時發現無法拖動元素,雖然實際業務上,手機也只是用來查看的,但為了論證手機上的觸摸事件,我還是在本節做個演示。
手機上觸控有三個重要事件touchstart,touchmove,touchend,分別表示開始觸摸,移動,及結束,與鼠標的mousedown,mousemove,mouseup對應。
基於前面示例代碼,因此把原來mousedown,mousemove,mouseup中的代碼抽象一下,Component中增加onDragStart,onDraging,onDragEnd三個方法,這樣無論是鼠標還是觸摸都調同樣的方法,
Component.prototype.onDragStart=function() { this.drag = true; } Component.prototype.onDraging=function(delta) { this.unselect(); //取消選中狀態 if (this.connector) //在拖動元素時如果有連線指示器則清除。 { this.destroy(); this.connector = null; }this.properties.x += delta.x; this.properties.y += delta.y; this.group.translate(delta.x,delta.y); this.redrawLines(); document.body.style.cursor = ‘move‘; } Component.prototype.onDragEnd=function() { }
修改Component中原來鼠標事件的代碼:
this.group.onMouseDown = function (event) { if (!me.designer.lining && !me.isLine) //非畫線狀態才允許拖動 if (event.event.button == 0) me.onDragStart(); else if (!me.isLine) me.designer.lineManager.dragStart(me.connector,event.point) } this.group.onMouseUp = function (event) { if (me.drag){ me.drag = false; me.onDragEnd() } else if (me.designer.lining && me.connector){ me.designer.lineManager.dragEnd(me.connector,event.point) } document.body.style.cursor = ‘default‘; } this.group.onMouseDrag = function (event) { if (me.drag && !me.designer.lining) //非畫線狀態才允許拖動 { me.onDraging(event.delta) } }
這樣修改後,鼠標操作(拖動組件移動位置)還是與原來一致,那現在我們要定義觸控事件,paperjs沒有touch的相關事件,那解決的思路是html5的canvas元素是支持觸摸事件的,通過試驗發現,觸控的坐標pageX是基於頁面的,而我們需要相對於畫布左上角,所以還需要$(this).offset()獲取畫布本身的偏移量,再查paperjs的說明文檔,發現group.hitTest(point)就是我們想要,遍歷所有組件,找到觸控位置的組件,然後調用組件的方法,代碼如下:(為了調試,在觸摸移動時輸出當前坐標)
var touchComponent=null; //當前拖動的組件 var touchPos=null; //上次位置 this.$element.on("touchstart",function(event){ event.preventDefault(); var touch=event.originalEvent.touches[0]||event.originalEvent.changedTouches[0]; var offset=$(this).offset(); $.each(me.nodes,function(idx,val){ try{ if(val.group){ var group=val.group.hitTest([touch.pageX-offset.left,touch.pageY-offset.top]) if (group) { if (!me.textPos) me.textPos = new paper.PointText({ point: [20, 40], content: ‘拖動:x:‘+touch.pageX+",y:"+touch.pageY, fillColor: ‘blue‘, fontFamily: ‘宋體‘, fontWeight: ‘bold‘, fontSize: 14 }); else me.textPos.set({ content: ‘拖動:x:‘+touch.pageX+",y:"+touch.pageY}) touchPos={x:touch.pageX-offset.left,y:touch.pageY-offset.top}; touchComponent=val; val.onDragStart(); return false; } } } catch(e){ me.textPos = new paper.PointText({ point: [20, 40], content: ‘錯誤:‘+e, fillColor: ‘blue‘, fontFamily: ‘宋體‘, fontWeight: ‘bold‘, fontSize: 14 }); } }) }) this.$element.on("touchmove",function(event){ event.preventDefault(); if (touchComponent) { var touch=event.originalEvent.touches[0]||event.originalEvent.changedTouches[0]; var offset=$(this).offset(); //當前位置減去上次位置,獲得偏移量 var delta={x:touch.pageX-offset.left-touchPos.x,y:touch.pageY-offset.top-touchPos.y}; touchComponent.onDraging(delta); touchPos={x:touch.pageX-offset.left,y:touch.pageY-offset.top};//當前位置 } }) this.$element.on("touchend",function(event){ event.preventDefault(); if (touchComponent) { touchComponent.onDragEnd() touchComponent=null; } })
發布到網站上,用手機瀏覽器看看,是不是就可以觸控拖動元素了,而且連線也會跟隨重繪呢?
後記:當然我們也可以更進一步的增加比如將組件拖動到畫布上,刪除等效果,只是邏輯類似,本節就不再演示了。
源代碼:sample.1.10.rar
(本文為原創,在引用代碼和文字時請註明出處)
12.手機端如何拖動組件--WEB設計器JQUERY插件講解(含源碼)