threejs画面拖动事件判断
文章目录
- 1. 根据相机是否移动来判断是否进行了拖拽
- 2.设置鼠标监听事件
- 小结
前因:想实现一个小功能,有一个参数 lockTiles
,当鼠标在屏幕上拖动时,参数 lockTiles
设置为 true
,停止拖动时,lockTiles
重设为 false
。
思考了一下,这个功能并不难,有两个方向可以实现这个功能:
- 根据相机是否移动来设置
- 设置鼠标监听事件,使用
mousedown
、mousemove
和mouseup
来判断是否进行了拖动
不过在对鼠标进行事件监听时遇到了一些坑点。。
1. 根据相机是否移动来判断是否进行了拖拽
查阅了 ThreeJS 文档,发现在轨道控制器 OrbitControls 中有几个事件可以用于判断相机是否进行了移动:
change
:当相机位置发生改变时触发start
:在对相机进行交互的开始时触发end
:在停止对相机进行交互时触发
基于我们的需求,这边使用的是 start
和 end
事件。
代码很简单:
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;}
}
不过,对于这种实现方式,当我们使用滚轮拉近和拉远相机时也会触发 start
和 end
事件,这个不是我们想要的效果:(lockTiles
的设置会反映到右上角的勾选框中,不过在滚轮滚动时,因为触发的太快因此看上去都是一直未被勾选的)
2.设置鼠标监听事件
拖拽操作可以分解为几个步骤:
- 鼠标左键按下
- 鼠标进行拖动
- 鼠标左键抬起
因此我们完全可以监听鼠标的动作来判断是否进行了拖拽操作。
具体是在鼠标按下时设置一个时间戳,当鼠标移动时,判断当前时间减去之前设置的时间戳是否大于某个阈值,若大于,我们认为此时进行了画面拖拽操作,也就是根据时间差来判断。
在 threejs 中,我们的画布 canvas
就是 renderer.domElement
,对其设置事件监听即可。
这时候遇到了坑点,正常来说 canvas
元素是支持鼠标事件 mousedown
和 mouseup
的,不过在实际测试时,发现 mousedown
和 mouseup
并没有工作,只有 mousemove
起效果了。
最后,经过多次尝试和google,发现可以使用 pointerdown
和 pointerup
事件来替代。(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
中的事件 start
、end
来判断,也可以使用 DOM 中的 pointerdown
、pointermove
和 pointerup
来判断,而使用 mousedown
、mouseup
事件是没有效果的。
threejs画面拖动事件判断相关推荐
- pyQt5中单击、双击、拖动事件区分
一般在处理单击.双击.拖动事件时会遇到以下问题: 双击时会产生两个额外的单击事件和两个释放事件 拖动时会在拖动开始处产生一个单击事件,在拖动结束时产生一个释放事件 故采用signal作为事件类型的标志 ...
- wxpython实现鼠标拖动事件
wxpython鼠标拖动事件小案例: #coding:UTF-8 import wxapp = wx.App() def dragEVT(event):if event.ButtonDown():pa ...
- php 判断html5,html5触摸事件判断滑动方向的实现
这篇文章主要介绍了html5触摸事件判断滑动方向的实现的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考. 为了给触摸界面提供有力支持, 触摸事件提供了响应用户对触摸屏或者触摸板上操作的能 ...
- js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法
js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法 javascript如何捕捉IE窗口失去焦点事件 window.onblur = function(e) { //you code }; 弹 ...
- wxpython frame鼠标拖动_Python wxpython模块响应鼠标拖动事件操作示例
本文实例讲述了Python wxpython模块响应鼠标拖动事件操作.分享给大家供大家参考,具体如下: wxpython鼠标拖动事件小案例: #coding:UTF-8 import wx app = ...
- demo h5 touch 移动_H5案例分享:移动端touch事件判断滑屏手势的方向
移动端touch事件判断滑屏手势的方向 方法一 当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY: 当触发touchmove事件时,在获取此时手指的横坐标 ...
- python鼠标拖拽功能_Python wxpython模块响应鼠标拖动事件操作示例
本文实例讲述了Python wxpython模块响应鼠标拖动事件操作.分享给大家供大家参考,具体如下: wxpython鼠标拖动事件小案例: #coding:UTF-8 import wx app = ...
- 游戏画面的印象判断价值和审美属性分析
之前Quora有个问题对于一款游戏谁扮演了更重要的角色(假定的三个选项,游戏设计师.美术和程序员),在几个有针对性的回复中,游戏设计师(Alexander Galasso.Pano Anthos和Pa ...
- H5鼠标拖动事件(drag)
H5鼠标拖动事件 一.元素拖动 二.相关事件 1.拖拽元素 (1)dargstart (2)drag (3)dragend 2.目标元素 (1)drop (2)dragover (3)dragente ...
最新文章
- python实现高校教务管理系统_基于Python技术的教务管理系统的研究与开发
- 通用计划明年推出自动驾驶出租车共享服务,可定制化设计车辆
- leetcode 236. 二叉树的最近公共祖先 思考分析
- 现在的00后都这么牛X的吗?
- struts1起服务报错
- 应用栈解决迷宫问题的C语言实现
- 第二十二章 职业道德规范
- Delphi基础教程图文版之数组
- linux硬盘支持fat32,Linux下,挂载windows管理格式的FAT32/NTFS 硬盘
- 2010计算机系助学金,计算机系贫困生助学金申请书
- 迪卡侬中国与阿里云达成合作;咖世家与恒天然在中国推出益生菌咖啡;默克高性能材料业务更名为电子科技 | 美通企业日报...
- css绘制梯形图形,及显示矩形图片
- HTTP和HTTPS的主要区别
- 简单的使用一下增强for循环
- Heartbeat的介绍及工作原理
- USB 调试工具(python2.7 + Tkinter + pyusb/pywinusb)
- github推送Please make sure you have the correct access rights and the repository exists.
- PyautoGui 常用教程(一篇就够)
- vuejs中v-if和v-show的区别以及v-show不起作用
- 类似高佣联盟怎么赚的?