12.手機端如何拖動組件--從零起步實現基於Html5的WEB設計器Jquery插件(含源碼)

 

 前面示例都只是展現在桌面瀏覽器顯示,當用手機瀏覽器打開時發現沒法拖動元素,雖然實際業務上,手機也只是用來查看的,但爲了論證手機上的觸摸事件,我仍是在本節作個演示。html

手機上觸控有三個重要事件touchstart,touchmove,touchend,分別表示開始觸摸,移動,及結束,與鼠標的mousedown,mousemove,mouseup對應。html5

基於前面示例代碼,所以把原來mousedown,mousemove,mouseup中的代碼抽象一下,Component中增長onDragStart,onDraging,onDragEnd三個方法,這樣不管是鼠標仍是觸摸都調一樣的方法,node

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中原來鼠標事件的代碼:canvas

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; } })

發佈到網站上,用手機瀏覽器看看,是否是就能夠觸控拖動元素了,並且連線也會跟隨重繪呢?網站

後記:固然咱們也能夠更進一步的增長好比將組件拖動到畫布上,刪除等效果,只是邏輯相似,本節就再也不演示了。this

源代碼:sample.1.10.rarurl

直接運行查看spa

(本文爲原創,在引用代碼和文字時請註明出處).net

 關鍵字:設計器源代碼,Web設計器,工做流設計器,jQuery插件,組態設計器,SCADA系統設計器,流程圖設計,表單設計建模,報表設計,可視化,設計時,運行時,輕量級開放平臺。

相關文章
相關標籤/搜索