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

相关文章

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

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Spring Boot 整合 Apache Flink 的详细过程

《SpringBoot整合ApacheFlink的详细过程》ApacheFlink是一个高性能的分布式流处理框架,而SpringBoot提供了快速构建企业级应用的能力,下面给大家介绍Spri... 目录Spring Boot 整合 Apache Flink 教程一、背景与目标二、环境准备三、创建项目 & 添

VSCode设置python SDK路径的实现步骤

《VSCode设置pythonSDK路径的实现步骤》本文主要介绍了VSCode设置pythonSDK路径的实现步骤,包括命令面板切换、settings.json配置、环境变量及虚拟环境处理,具有一定... 目录一、通过命令面板快速切换(推荐方法)二、通过 settings.json 配置(项目级/全局)三、

pytest+allure环境搭建+自动化实践过程

《pytest+allure环境搭建+自动化实践过程》:本文主要介绍pytest+allure环境搭建+自动化实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、pytest下载安装1.1、安装pytest1.2、检测是否安装成功二、allure下载安装2.

Pytorch介绍与安装过程

《Pytorch介绍与安装过程》PyTorch因其直观的设计、卓越的灵活性以及强大的动态计算图功能,迅速在学术界和工业界获得了广泛认可,成为当前深度学习研究和开发的主流工具之一,本文给大家介绍Pyto... 目录1、Pytorch介绍1.1、核心理念1.2、核心组件与功能1.3、适用场景与优势总结1.4、优

使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)

《使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)》字体设计和矢量图形处理是编程中一个有趣且实用的领域,通过Python的matplotlib库,我们可以轻松将字体轮廓... 目录背景知识字体轮廓的表示实现步骤1. 安装依赖库2. 准备数据3. 解析路径指令4. 绘制图形关键

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧