zoukankan      html  css  js  c++  java
  • 12.手机端如何拖动组件--从零起步实现基于Html5的WEB设计器Jquery插件(含源码)

     前面示例都只是展示在桌面浏览器显示,当用手机浏览器打开时发现无法拖动元素,虽然实际业务上,手机也只是用来查看的,但为了论证手机上的触摸事件,我还是在本节做个演示。

    手机上触控有三个重要事件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

    直接运行查看

    (本文为原创,在引用代码和文字时请注明出处)

     
    关键字
    :设计器源代码,Web设计器,工作流设计器,jQuery插件,组态设计器,SCADA系统设计器,流程图设计,表单设计建模,报表设计,可视化,设计时,运行时,轻量级开放平台。

  • 相关阅读:
    System.Reflection.MemberInfo.cs
    System.Reflection.CustomAttributeData.cs
    System.Reflection.CustomAttibuterNamedArgument.cs
    数据文件、日志文件、归档文件、控制文件、参数文件及RMAN备份数据库信息查询
    RMAN完整全备份
    RMAN增量备份-备份保留策略-设置备份集属性
    安装sql server 2008 management studio时,提示升级VS2008 到 SP1
    RMAN备份各种物理文件
    ORACLE物理存储结构
    视图、序列、索引、同义词
  • 原文地址:https://www.cnblogs.com/coolalam/p/9724752.html
Copyright © 2011-2022 走看看