图形编辑器中JS实现防误操作之拖拽阻塞
图形编辑器中
在图形编辑器中,想象这么一个场景,我们撤销了一些重要的操作,然后想选中一个图形,看看它的属性。你点了上去,然后你发现你再也无法重做了。
你以为你点了一下,但其实你点击的时候,鼠标还是小小移动了一点,飘了一个像素点。对编辑器来说,它识别到让图形移动一个像素点的操作,就生成了一个新的版本,然后重做栈(redoStack)被清空了,你退回前的操作就没了。
为了解决这类用户微小操作的问题,我们可以巧妙地给拖拽行为加一个 阻塞阈值。具体就是就是按下鼠标后,移动鼠标的距离要大于某个值,我们才认为发生了拖拽,并执行对应工具的逻辑。
下面为我们要实现的效果。此处为了更好地演示效果,将阈值设置得很大。通常设置个 4px 就够了。
可以看到,按下鼠标然后移动,如果移动的位移太小,矩形是不会被移动的,直到达到一定位移阈值后,矩形才会乖乖听话跟随鼠标进行移动。
阈值表示位移距离,使用的是视口坐标系,而不是场景坐标系。
代码改造
原来的逻辑:
let isPressing = false; let currentTool = null; // 当前工具对象 // 鼠标按下 function handleDown(e) { isPressing = true; currentTool.start(e); } // 鼠标移动 function handleMove(e) { if (isPressing) { currentTool.drag(e); } else { // 非拖拽的移动事件 // 比如选择工具停留在图形上,图形要高亮,此时没发生拖拽 currentTool.move(e); } } // 鼠标释放 function handleUp(e) { currentTool.end(e); isPressing = false; }
鼠标按下时,isPressing 设置为 true,表示发生了鼠标按下事件。
此时鼠标再移动,我们就能知道这是一个 “拖拽” 的行为,即按下鼠标不放然后移动鼠标的行为。此时调用工具对象的 drag 方法。
最后鼠标释放,将状态 isPressing 重置。
现在我们进行改造。
let isPressing = false; let currentTool = null; // 当前工具对象 let isEnableDragging = false; // 是否调用工具对象的 drag 方法 let startPos = null; // 保存鼠标按下时的坐标 const blockStep = 4; // 阈值 function handleDown(e) { isPressing = true; isEnableDragging = false; startPos = { x: e.clientX, y: e.clientY }; currentTool.start(e); } function handleMove(e) { // 判断位移是否突破阈值,是的话更新状态为 “可拖拽” if ( !isEnableDragging && (Math.abs(e.clientX - startPos.x) > blockStep || Math.abs(e.clientX - startPos.x) > blockStep) ) { isEnableDragging = true; } if (isPressing) { if (isEnableDragging) { // “可拖拽” 状态,调用工具的 drag 方法 currentTool.drag(e); } } else { currentTool.move(e); } } function handleUp(e) { currentTool.end(e); // 初始化状态 isPressing = false; isEnableDragging = false; startPos = null; }
核心思路是引入 isEnableDragging 状态,表示鼠标移动时,是否达到移动的条件。
我们在鼠标移动事件中,计算鼠标按下和鼠标移动之间的距离是否超过某个值,如果超过阈值,就将 isEnableDragging 状态转换为 true。
然后判断 isEnableDragging 为 true,就调用工具对象的 drag 方法。
需要注意的是,不要只用位移距离来判断是否可以拖拽,要配合状态。否则突破阈值后,又移动回来,你会发现你又卡住了,因为此时阈值因为再次计算,没能达到阈值。
所以加了个 isEnableDragging 状态,在第一次突破阈值设置为 true 后,就再也不用计算位移了,之后一直都是可拖拽状态,直到鼠标释放重置状态。
结尾
拖拽阻塞是开发图形编辑器的一点小细节,并不复杂,但能带来很好的用户体验。
以上就是图形编辑器中JS实现防误操作之拖拽阻塞的详细内容,更多关于JS 拖拽阻塞的资料请关注脚本之家其它相关文章!
相关文章
select、radio表单回显功能实现避免使用jquery载入赋值
select、radio表单回显避免使用jquery载入赋值,最好的做法是:在jsp页面进行逻辑判断,具体实现如下,感兴趣的朋友可以参考下哈,希望对大家有所帮助2013-06-06JavaScript创建对象方式总结【工厂模式、构造函数模式、原型模式等】
这篇文章主要介绍了JavaScript创建对象方式,结合实例形式总结分析了工厂模式、构造函数模式、原型模式等各种常见的javascript对象创建方式与相关操作注意事项,需要的朋友可以参考下2018-12-12Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
这篇文章主要介绍了Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下2016-06-06JavaScript设计模式之原型模式分析【ES5与ES6】
这篇文章主要介绍了JavaScript设计模式之原型模式,简单描述了原型模式的概念、原理,并结合实例形式分析了ES5与ES6实现原型模式的相关操作技巧,需要的朋友可以参考下2018-07-07
最新评论