12.手机端如何拖动组件--WEB设计器JQUERY插件讲解(含源码)
Posted DotNET 程序猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12.手机端如何拖动组件--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系统设计器,流程图设计,表单设计建模,报表设计,可视化,设计时,运行时,轻量级开放平台。
以上是关于12.手机端如何拖动组件--WEB设计器JQUERY插件讲解(含源码)的主要内容,如果未能解决你的问题,请参考以下文章
Delphi 自定义组件,拖动时无法在设计器中定位(顶部/左侧属性的自定义设置器)