大家好,我是前端西瓜哥。在图形编辑器中,想象这么一个场景,我们撤销了一些重要的操作,然后想选中一个图形,看看它的属性。你点了上去,然后你发现你再也无法重做了。

你以为你点了一下,但其实你点击的时候,鼠标还是小小移动了一点,飘了一个像素点。对编辑器来说,它识别到让图形移动一个像素点的操作,就生成了一个新的版本,然后重做栈(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 后,就再也不用计算位移了,之后一直都是可拖拽状态,直到鼠标释放重置状态。

结尾

拖拽阻塞是开发图形编辑器的一点小细节,并不复杂,但能带来很好的用户体验。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。

图形编辑器:拖拽阻塞优化相关推荐

  1. ue编辑器拖拽上传图片_Typora + PicGo打造超好用的Markdown编辑器

    工欲善其事必先利其器,既然决定要写作啦,一个好用的编辑器是必不可少的工具.相信作为一个程序员,大家应该也都比较了解Markdown语法,经过重重对比,我选定了Typora来作为Markdown编辑器. ...

  2. ue编辑器拖拽上传图片_editor.md实现拖拽剪切复制粘贴上传图片,文件插件

    editor.md作为一款Markdown编辑器,界面美观,功能强大 但是图片,文件上传方面缺少了剪切,拖拽上传,有那么一点每中不足,下面就简单实现一个,废话不多说,直接上代码. uploadImg. ...

  3. ue编辑器拖拽上传图片_为百度UE编辑器上传图片添加水印功能

    前些日子把phpcms的内置编辑器改成了百度UE编辑器,非常好用,但是有个地方不是很满意,就是没法给上传的图片加水印了,经过一番研究终于实现了出来,分享给大家 UEditor编辑器上传图片是自动提取的 ...

  4. canvas图形编辑器

      原文地址:http://jeffzhong.space/2017/11/02/drawboard/   使用canvas进行开发项目,我们离不开各种线段,曲线,图形,但每次都必须用代码一步一步去实 ...

  5. 13.鼠标拖拽:案例:鼠标拖拽小方块,小方格跟着移动(桌面图标拖动)

    目录 一:案例鼠标拖拽小方块,小方格跟着移动(桌面图标拖动) 二:取消拖拽文字的行为 1.没取消前: 2.取消后: 三:鼠标拖拽案例优化: 如果有好多个小盒子要做拖拽,一个一个加上面的1,2,3步太麻 ...

  6. vue+openlayers中实现图片展示与图片的拖拽和放大缩小(一)

    前言: openlayers中渲染图片是有多种方法的, Icon ,Image 等等都可以实现将图片放到地图上面,但是操作图片的话,方法比较少了,这里是配合 ol-ext 来实现的. 相关资料: 1. ...

  7. 小程序Android端movable-view拖拽卡顿掉帧的优化

    背景: 最近项目中使用到movable-view来做一个拖拽排序的功能,等到功能都实现完成后到真机测试发现,拖拽动画在Android端存在严重的卡顿掉帧,及其不跟手,但是在IOS端却挺流畅.查阅Goo ...

  8. npm 可视化html编辑器,超给力 Vue.js 可视化H5拖拽编辑器Quark-H5

    前两天有分享一个鲁班H5移动端页面生成器.今天再给大家推荐一款超优秀的Vue H5可视化布局编辑器QuarkH5. quark-h5 基于 vue.js 开源的H5可视化拖放编辑器,star高达1.7 ...

  9. PPT中要实现图片或图形的任意拖拽

    PPT中要实现图片或图形的任意拖拽需要通过VBA编程.现介绍利用图像控件实现图片任意拖拽的方法: 1.在演示文稿插入图像控件,打开属性窗口,将picture设成你想拖动的图片,遗憾的是Image控件不 ...

最新文章

  1. 在CentOS/Debian/Ubuntu上编译安装最新版 GCC 8 , cmake 3 和ninja
  2. Balanced Lineup POJ - 3264(线段树模板+查询比大小+建树)
  3. Codeforces-462C. A Twisty Movement
  4. 美司法部揭秘俄黑客窃取雅虎5亿帐户资料全过程
  5. java 二叉树_拼多多Java开发1234面:二叉树+负载均衡+MySQL+Redis+高并发
  6. 【转】我的opengl编程学习(二)(混合、深度测试、雾化、
  7. [转]C语言如何获得精确到毫秒的时间
  8. TOMCAT下应用部署新法(/META-INF/context.xml)
  9. Linux环境下的jdk安装(大数据环境)
  10. 【信号检测】认知无线电的信号检测算法matlab仿真:能量检测,循环平稳检测,匹配滤波检测
  11. 生产环境 JDK6 升级 JDK8
  12. 阿里天池大数据竞赛(杂)
  13. 什么是word文件只读模式?
  14. PVR图像文件格式初探
  15. 如何申请屏蔽垃圾短信
  16. Linux 服务器一键测速脚本工具:GreenBench
  17. 32位计算机如何升级,32位改64位系统怎么安装 32位怎么升级64位系统
  18. python新闻内容爬虫专用包newspaper详细教程
  19. MySQL数据库操作-查看数据库 (SHOW DATABASES)
  20. C++构造函数初始化列表与构造函数中的赋值的区别

热门文章

  1. c语言实现万能求积分
  2. Linus Torvalds称讨厌被人崇拜
  3. Idea无法自动补全代码,ctrl+Alt+v无法使用解决方法
  4. 项目上线阿里云(二) 在云上(基于ubuntu系统)安装JDK8,tomcat8
  5. APS高级计划排程系统,工厂各部门实施前后有哪些区别?
  6. 梦之光芒Monyer (全关解析)
  7. GitHub基本操作
  8. 【python柱状图】图例大小、位置,X轴刻度大小,旋转角度
  9. python绘制小提琴图_matplotlib 小提琴图(violin plot)
  10. 微信小程序中wxml中用data-id传出的数据在js中的获取方法。