H5页面手绘轨迹路径-过程中允许拖动+缩放地图

2024-03-04 11:44

本文主要是介绍H5页面手绘轨迹路径-过程中允许拖动+缩放地图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文章可以参考解决的问题:H5端的多指、单指操作混乱的问题; mapbox-gl手绘轨迹线。

希望本文能帮助到其他人!
 

对于“在H5页面支持在地图上手绘轨迹"这个需求,从需求层面看比较简单。

作为开发,你会怎么做?

第一映像是 锁定地图,绘制过程中地图不跟随移动,否则手指在移动过程中手指的坐标不会变化,这样就完成了这一需求。

可以的!完全没问题。

但优秀吗?

从用户体验上,一旦锁定地图,在绘制过程中用户要操作的区域到可视区之外的话,则不好完了,怎么办?增加锁定、释放,移动等一系列辅助按钮?

功能上可以了,满足。

但完美吗?

从UI层面,增加了按钮,增加用户操作,体验不太好。

怎么让用户操作起来更丝滑?尽量保留地图的原生操作:1. 双指放大缩小地图。 2. 单指移动地图。直接上代码片段:

// 几种特殊情况: 多指开始->中间一个一个单指结束 ,单指开始 -> 中间加入多指。 处理方式:只要存在多指情况则不处理,且注意延迟。
let lnglats = [], moveTempLnglat = [], lastLnglat, locusChanging = false, touchCount = 0,handleTimer, singleTouch = true, handling = false // 1-单指, 2-双指。从开始start 到结束 end 一次操作才算完成
const tolerance = {10: 1000, 11: 1000, 12: 800, 13: 400, 14: 200, 15: 100, 16: 50, 17: 20, 18: 10, 19: 5, 20: 2, 21: 1}
const setLocus = () => {map.getSource("mylocus").setData({type: "FeatureCollection",features: [{type: "Feature",properties: {},geometry: {type: "LineString",coordinates: lnglats}}]})
}const startHandler = e => {const touchLen = e.originalEvent.changedTouches.lengthtouchCount += touchLen// 任一超一个触点,则视为多指,必须在所有触点释放后才能做后续操作if (touchCount > 1) {singleTouch = false}// 检查是否在附近,只有在附近才视为连续绘制if (singleTouch && touchLen === 1 && lnglats.length > 1) {const dis = turf.rhumbDistance(turf.point(lnglats[lnglats.length - 1]), turf.point([e.lngLat.lng, e.lngLat.lat]), {units: "meters"})if (dis > tolerance[Math.round(map.getZoom())]){map.dragPan.enable()return}}clearTimeout(handleTimer)// 清空移动预存moveTempLnglat = []// 避免双指延迟handleTimer = setTimeout(() => {if (singleTouch && touchLen === 1) {handling = truelnglats.push([e.lngLat.lng, e.lngLat.lat], ...moveTempLnglat.splice(0, moveTempLnglat.length))setLocus()}}, 200)
}const moveHandler = e => {const touchLen = e.originalEvent.targetTouches.lengthif (singleTouch && touchLen === 1) {if (handling) {lnglats.push([e.lngLat.lng, e.lngLat.lat])setLocus()} else {moveTempLnglat.push([e.lngLat.lng, e.lngLat.lat])}}
}const endHandler = e => {const touchLen = e.originalEvent.changedTouches.lengthtouchCount -= touchLen// 之前是单指模式,则开始动作if (singleTouch && touchLen === 1 && handling) {lnglats.push([e.lngLat.lng, e.lngLat.lat])setLocus()}if (touchCount === 0) {singleTouch = truehandling = false}if (locusChanging) {map.dragPan.disable()}
}const startChangeLocus = () => {const map = mapObj.valuelnglats = []moveTempLnglat = []handling = falsemap.dragPan.disable()// 测试:锁定地图,不允许拖动if (!map.getLayer("mylocus")) {map.addLayer({id: "mylocus",type: "line",source: {type: "geojson",data: {type: "FeatureCollection", features: []}}})} else {setLocus()}if (!locusChanging) {map.on("touchstart", startHandler)map.on("touchmove", moveHandler)map.on("touchend", endHandler)}locusChanging = true
}
const stopChangeLocus = () => {const map = mapObj.valuemap.dragPan.enable()map.off("touchstart", startHandler)map.off("touchmove", moveHandler)map.off("touchend", endHandler)locusChanging = false
}

主要思路: 只要触发了多触点,则视为当前多指操作,不做绘制;同时,预留了双指两个指头不同步的情况。

总结:

在使用触摸事件时,注意 changeTouches,touches,targetTouches 属性的在touchstart,touchmove,touchend 事件中分别的含义。

TouchEvent.changedTouches - Web API 接口参考 | MDN

TouchEvent.targetTouches - Web API 接口参考 | MDN

TouchEvent.touches - Web API 接口参考 | MDN

这篇关于H5页面手绘轨迹路径-过程中允许拖动+缩放地图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/773074

相关文章

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal