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

相关文章

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并