1. 程式人生 > >12.手機端如何拖動組件--WEB設計器JQUERY插件講解(含源碼)

12.手機端如何拖動組件--WEB設計器JQUERY插件講解(含源碼)

鼠標事件 component 移動 edt design 說明文檔 mov each offset

關鍵字:設計器源代碼,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插件講解(含源碼)