文章目录

  • 1. 根据相机是否移动来判断是否进行了拖拽
  • 2.设置鼠标监听事件
  • 小结

  前因:想实现一个小功能,有一个参数 lockTiles,当鼠标在屏幕上拖动时,参数 lockTiles 设置为 true,停止拖动时,lockTiles 重设为 false

  思考了一下,这个功能并不难,有两个方向可以实现这个功能:

  • 根据相机是否移动来设置
  • 设置鼠标监听事件,使用 mousedownmousemovemouseup 来判断是否进行了拖动

  不过在对鼠标进行事件监听时遇到了一些坑点。。

1. 根据相机是否移动来判断是否进行了拖拽

  查阅了 ThreeJS 文档,发现在轨道控制器 OrbitControls 中有几个事件可以用于判断相机是否进行了移动:

  • change:当相机位置发生改变时触发
  • start:在对相机进行交互的开始时触发
  • end:在停止对相机进行交互时触发

  基于我们的需求,这边使用的是 startend 事件。

  代码很简单:

controls = new OrbitControls( camera, renderer.domElement );controls.addEventListener('start', lock);
controls.addEventListener('end', unlock);function lock(e) {if (!param.lockTiles) {console.log('lock')param.lockTiles = true;}
}function unlock(e) {if (param.lockTiles) {console.log('unlock')param.lockTiles = false;}
}

  不过,对于这种实现方式,当我们使用滚轮拉近和拉远相机时也会触发 startend 事件,这个不是我们想要的效果:(lockTiles 的设置会反映到右上角的勾选框中,不过在滚轮滚动时,因为触发的太快因此看上去都是一直未被勾选的)

2.设置鼠标监听事件

  拖拽操作可以分解为几个步骤:

  1. 鼠标左键按下
  2. 鼠标进行拖动
  3. 鼠标左键抬起

  因此我们完全可以监听鼠标的动作来判断是否进行了拖拽操作。

  具体是在鼠标按下时设置一个时间戳,当鼠标移动时,判断当前时间减去之前设置的时间戳是否大于某个阈值,若大于,我们认为此时进行了画面拖拽操作,也就是根据时间差来判断。

  在 threejs 中,我们的画布 canvas 就是 renderer.domElement,对其设置事件监听即可。

  这时候遇到了坑点,正常来说 canvas 元素是支持鼠标事件 mousedownmouseup 的,不过在实际测试时,发现 mousedownmouseup 并没有工作,只有 mousemove 起效果了。

  最后,经过多次尝试和google,发现可以使用 pointerdownpointerup 事件来替代。(pointer event)

PointerEvent 接口继承了所有 MouseEvent 中的属性,以保障原有为鼠标事件所开发的内容能更加有效的迁移到指针事件。

  然后,基于 pointer 事件,写了一个简单的拖拽触发判断类:

export default class MouseDragCheck {constructor(props) {this.dom = props.dom;this.downCb = props.downCb; // 几个事件触发时的回调函数this.upCb = props.upCb;this.moveCb = props.moveCb;this.startClickDown = -1;    // 鼠标按下的时间戳this.dragInterval = 100;    // 鼠标拖动的毫秒间隔,大于 100ms 认为它在拖动}addEventListeners = () => {const dom = this.dom;dom.addEventListener('pointerdown', this.mouseDown, false);dom.addEventListener('pointermove', this.mouseMove, false);dom.addEventListener('pointerup', this.mouseUp, false);};removeEventListeners = () => {const dom = this.dom;dom.removeEventListener('pointerdown', this.mouseDown, false);dom.removeEventListener('pointermove', this.mouseMove, false);dom.removeEventListener('pointerup', this.mouseUp, false);};mouseDown = (e) => {this.startClickDown = new Date().getTime();if (this.downCb) {this.downCb(e);}};mouseMove = (e) => {const cur = new Date().getTime();if (this.startClickDown !== -1 && cur - this.startClickDown > this.dragInterval) {if (this.moveCb) {this.moveCb(e);}}};mouseUp = (e) => {this.startClickDown = -1;if (this.upCb) {this.upCb(e);}};
}

  然后调用这个类来完成我们对 lockTiles 属性设置的需求:

let dragCheck = new DragCheck({dom: renderer.domElement,moveCb: lock,upCb: unlock
});...
if (track) {dragCheck.addEventListeners();
} else {dragCheck.removeEventListeners();
}

  这样实现的话,只有画面在进行拖拽时能触发回调,而滚轮滚动时则不会触发:

小结

  在 ThreeJS 中对画面的拖拽判断可以使用 OrbitControls 中的事件 startend 来判断,也可以使用 DOM 中的 pointerdownpointermovepointerup 来判断,而使用 mousedownmouseup 事件是没有效果的。

threejs画面拖动事件判断相关推荐

  1. pyQt5中单击、双击、拖动事件区分

    一般在处理单击.双击.拖动事件时会遇到以下问题: 双击时会产生两个额外的单击事件和两个释放事件 拖动时会在拖动开始处产生一个单击事件,在拖动结束时产生一个释放事件 故采用signal作为事件类型的标志 ...

  2. wxpython实现鼠标拖动事件

    wxpython鼠标拖动事件小案例: #coding:UTF-8 import wxapp = wx.App() def dragEVT(event):if event.ButtonDown():pa ...

  3. php 判断html5,html5触摸事件判断滑动方向的实现

    这篇文章主要介绍了html5触摸事件判断滑动方向的实现的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考. 为了给触摸界面提供有力支持, 触摸事件提供了响应用户对触摸屏或者触摸板上操作的能 ...

  4. js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法

    js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法 javascript如何捕捉IE窗口失去焦点事件 window.onblur = function(e) { //you code }; 弹 ...

  5. wxpython frame鼠标拖动_Python wxpython模块响应鼠标拖动事件操作示例

    本文实例讲述了Python wxpython模块响应鼠标拖动事件操作.分享给大家供大家参考,具体如下: wxpython鼠标拖动事件小案例: #coding:UTF-8 import wx app = ...

  6. demo h5 touch 移动_H5案例分享:移动端touch事件判断滑屏手势的方向

    移动端touch事件判断滑屏手势的方向 方法一 当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY: 当触发touchmove事件时,在获取此时手指的横坐标 ...

  7. python鼠标拖拽功能_Python wxpython模块响应鼠标拖动事件操作示例

    本文实例讲述了Python wxpython模块响应鼠标拖动事件操作.分享给大家供大家参考,具体如下: wxpython鼠标拖动事件小案例: #coding:UTF-8 import wx app = ...

  8. 游戏画面的印象判断价值和审美属性分析

    之前Quora有个问题对于一款游戏谁扮演了更重要的角色(假定的三个选项,游戏设计师.美术和程序员),在几个有针对性的回复中,游戏设计师(Alexander Galasso.Pano Anthos和Pa ...

  9. H5鼠标拖动事件(drag)

    H5鼠标拖动事件 一.元素拖动 二.相关事件 1.拖拽元素 (1)dargstart (2)drag (3)dragend 2.目标元素 (1)drop (2)dragover (3)dragente ...

最新文章

  1. python实现高校教务管理系统_基于Python技术的教务管理系统的研究与开发
  2. 通用计划明年推出自动驾驶出租车共享服务,可定制化设计车辆
  3. leetcode 236. 二叉树的最近公共祖先 思考分析
  4. 现在的00后都这么牛X的吗?
  5. struts1起服务报错
  6. 应用栈解决迷宫问题的C语言实现
  7. 第二十二章 职业道德规范
  8. Delphi基础教程图文版之数组
  9. linux硬盘支持fat32,Linux下,挂载windows管理格式的FAT32/NTFS 硬盘
  10. 2010计算机系助学金,计算机系贫困生助学金申请书
  11. 迪卡侬中国与阿里云达成合作;咖世家与恒天然在中国推出益生菌咖啡;默克高性能材料业务更名为电子科技 | 美通企业日报...
  12. css绘制梯形图形,及显示矩形图片
  13. HTTP和HTTPS的主要区别
  14. 简单的使用一下增强for循环
  15. Heartbeat的介绍及工作原理
  16. USB 调试工具(python2.7 + Tkinter + pyusb/pywinusb)
  17. github推送Please make sure you have the correct access rights and the repository exists.
  18. PyautoGui 常用教程(一篇就够)
  19. vuejs中v-if和v-show的区别以及v-show不起作用
  20. 类似高佣联盟怎么赚的?

热门文章

  1. 对“单子模式”的补充
  2. 架构篇:什么才是真正的架构设计?
  3. 基于 SpringBoot 的仿豆瓣平台【源码分享】
  4. 阿里某程序员吐槽:年终奖被金融行业的老婆完爆!自己奖金15万,老婆奖金66万!...
  5. 今天说的是必须要熟练掌握的归并排序
  6. 大白话聊聊 Kafka 的架构原理和网络设计,它的性能高在什么地方?
  7. 原创整理:92份面试题,累计3625页,肝的太累了
  8. 美团外卖持续交付的前世今生
  9. 面试热点|理解TCP/IP传输层拥塞控制算法
  10. 为什么用了索引之后,查询就会变快?