potree实现触摸选点功能

1,878 阅读3分钟

欢迎转载,转载需带着文章出处链接~~,希望我的经验能帮到你,有问题可以点我头像加我微信 本文章仅对遇到的问题提供一个解决思路,对于迫切想要实现功能效果的人来说,希望能稍微沉下心观看,或者直接观看思路部分,或者直接观看完整代码 本文章的代码并不能直接拿来使用,完整代码只是本篇文章解决的问题需要用到的代码,如果直接使用可能会有报错,只要修改一下代码既可使用~~~

potree触摸修改

potree本身只有鼠标事件可以对点、区域、高程等等measurement进行选择,触摸事件只能进行视角的改变

-参考-

程序园 JavaScript将触摸事件映射到鼠标事件


-说明-

potree触摸事件效果如下:

① 单指操作,进行视角的旋转
② 双指操作,进行视角的缩放
③ 三指操作,进行视角的平移

-主要版本-

potreejs 1.6


-思路-

1、查找代码相关位置 2、通过js代码进行操作 3、通过将touch事件映射到mouse事件上 4、通过重写部分touch代码


-过程-

1、查找代码相关位置

通过定位touchstart,找到相对应的位置

touch事件绑定位置

touch事件方法

potree相关操作绑定的类

2、通过js代码进行操作

最初是想通过js代码来进行操作,将touch的方法都替换成mouse的方法,运行代码会报错,发现事件返回的event参数有所不同,修改event,将event重新赋值,代码如下:

event=event.touches[0];

这样会面临一个问题,event.buttonevent.buttons无法获得,根据event.touches.length来进行判断,代码如下:

event.button =event.touches.length;
event.buttons =2 ** (event.touches.length - 1);

这样实现了1根指头代表鼠标左键,2根指头代表鼠标右键,可惜这种方法无法实现将measurement添加成功。

3、通过将touch事件映射到mouse事件上

映射代码如下:

function touchHandler(event){
  var touches = event.changedTouches,
    first = touches[0],
    type = "";
  switch(event.type){
    case "touchstart":
      type = "mousedown";
      break;
    case "touchmove":
      type = "mousemove";
      break;        
    case "touchend":
      type = "mouseup";
      break;
    default:
      return;
  }

  // initMouseEvent方法传参,可以百度查找;
  var simulatedEvent = document.createEvent("MouseEvent");
  simulatedEvent.initMouseEvent(type, true, true, window, 1, 
    first.screenX, first.screenY, 
    first.clientX, first.clientY, false, 
    false, false, false, 0/*left*/, null);
  first.target.dispatchEvent(simulatedEvent);
  event.preventDefault();
}
function init() {
  document.addEventListener("touchstart", touchHandler, true);
  document.addEventListener("touchmove", touchHandler, true);
  document.addEventListener("touchend", touchHandler, true);
  document.addEventListener("touchcancel", touchHandler, true);    
}

经调整修改,整合到potree中,代码如下:

potree整合代码

这时发现多指操作时,一直会触发单指,这里折腾了好长时间,然后换了其他方法。

4、通过重写部分touch代码

在新增的时候touch变为增加,不可操控视角 不新增的时候touch变为视角操控

4.1、声明是否增加measure变量isAddM到全局变量中

这里我使用true为不触摸,false为触摸

window.isAddM =true;

4.2、声明触摸手指数量变量touchNum到全局变量中

window.touchNum =0;

4.3、找到创建measure的地方

① 首先找到PointPanel,查看新增方法,发现方法为marker_added

PointPanel代码位置

② 查找marker_added,定位到方法addMarker

marker_added代码位置

addMarker方法

③ 触发时改变isAddM
isAddM =false;

4.4、修改onTouchStartonTouchEndonTouchMove方法

将原先的代码放到isAddM ==true的位置,三个方法都要修改,如下所示:

修改后的touch方法

4.5、实现双指增加measure

除了PointPanel点击后可以直接增加,其他的panel都需要通过鼠标右键来增加,这里通过增加完成后随意触发其他事件或者阻止冒泡即可成功增加。

① touchstart判断多指,代码如下:

修改touchNum的数量即可

② touchend结束时,判断如果是多指就退出,代码如下:

先减1,如果大于0代表多指

既可实现效果

-完整代码-

onTouchStart (e) {
		if(isAddM){
			if (this.logMessages) console.log(this.constructor.name + ': onTouchStart');

			e.preventDefault();

			if (e.touches.length === 1) {
				let rect = this.domElement.getBoundingClientRect();
				let x = e.touches[0].pageX - rect.left;
				let y = e.touches[0].pageY - rect.top;
				this.mouse.set(x, y);

				this.startDragging(null);
			}

			
			for (let inputListener of this.getSortedListeners()) {
				inputListener.dispatchEvent({
					type: e.type,
					touches: e.touches,
					changedTouches: e.changedTouches
				});
			}
		}else{
			touchNum ++;
		}
	}

	onTouchEnd (e) {
		if(isAddM){
			if (this.logMessages) console.log(this.constructor.name + ': onTouchEnd');

			e.preventDefault();

			for (let inputListener of this.getSortedListeners()) {
				inputListener.dispatchEvent({
					type: 'drop',
					drag: this.drag,
					viewer: this.viewer
				});
			}

			this.drag = null;

			for (let inputListener of this.getSortedListeners()) {
				inputListener.dispatchEvent({
					type: e.type,
					touches: e.touches,
					changedTouches: e.changedTouches
				});
			}
		}else{
			touchNum --;
			if(touchNum >=1){
				touchNum =0;
				isAddM =true;
				e.preventDefault();
			}
		}
	}

	onTouchMove (e) {
		if(isAddM){
			if (this.logMessages) console.log(this.constructor.name + ': onTouchMove');

			e.preventDefault();

			if (e.touches.length === 1) {
				let rect = this.domElement.getBoundingClientRect();
				let x = e.touches[0].pageX - rect.left;
				let y = e.touches[0].pageY - rect.top;
				this.mouse.set(x, y);

				if (this.drag) {
					this.drag.mouse = 1;

					this.drag.lastDrag.x = x - this.drag.end.x;
					this.drag.lastDrag.y = y - this.drag.end.y;

					this.drag.end.set(x, y);

					if (this.logMessages) console.log(this.constructor.name + ': drag: ');
					for (let inputListener of this.getSortedListeners()) {
						inputListener.dispatchEvent({
							type: 'drag',
							drag: this.drag,
							viewer: this.viewer
						});
					}
				}
			}

			for (let inputListener of this.getSortedListeners()) {
				inputListener.dispatchEvent({
					type: e.type,
					touches: e.touches,
					changedTouches: e.changedTouches
				});
			}
		}

		// DEBUG CODE
		// let debugTouches = [...e.touches, {
		//	pageX: this.domElement.clientWidth / 2,
		//	pageY: this.domElement.clientHeight / 2}];
		// for(let inputListener of this.getSortedListeners()){
		//	inputListener.dispatchEvent({
		//		type: e.type,
		//		touches: debugTouches,
		//		changedTouches: e.changedTouches
		//	});
		// }
	}