您的位置:首页 > 新闻 > 热点要闻 > 长春做网站价格_室内设计要学哪些科目_站长之家域名查询官网_宁波优化网页基本流程

长春做网站价格_室内设计要学哪些科目_站长之家域名查询官网_宁波优化网页基本流程

2025/4/19 9:11:29 来源:https://blog.csdn.net/m0_46281382/article/details/147294288  浏览:    关键词:长春做网站价格_室内设计要学哪些科目_站长之家域名查询官网_宁波优化网页基本流程
长春做网站价格_室内设计要学哪些科目_站长之家域名查询官网_宁波优化网页基本流程

概述

TouchZoomMap 类的一个扩展方法,是 Leaflet 实现触摸设备双指缩放的处理器,用于在移动端通过双指手势控制地图的缩放。

源码分析

源码实现

TouchZoom的源码实现如下:

Map.mergeOptions({touchZoom: Browser.touch, // 仅在触摸设备上启用bounceAtZoomLimits: true, // 缩放超出限制时是否回弹
});export var TouchZoom = Handler.extend({addHooks: function () {// 添加 CSS 类(可能用于样式或标记状态)DomUtil.addClass(this._map._container, "leaflet-touch-zoom");// 监听触摸开始事件DomEvent.on(this._map._container, "touchstart", this._onTouchStart, this);},removeHooks: function () {// 移除 CSS 类和事件监听DomUtil.removeClass(this._map._container, "leaflet-touch-zoom");DomEvent.off(this._map._container, "touchstart", this._onTouchStart, this);},_onTouchStart: function (e) {var map = this._map;// 检查是否双指触摸,且地图未在动画中if (!e.touches ||e.touches.length !== 2 ||map._animating ||this._zooming) {return;}// 计算两指初始位置(转换为地图容器坐标)var p1 = map.mouseEventToContainerPoint(e.touches[0]),p2 = map.mouseEventToContainerPoint(e.touches[1]);// 确定缩放中心点this._centerPoint = map.getSize()._divideBy(2); // 地图中心this._startLatLng = map.containerPointToLatLng(this._centerPoint);// 如果非center模式,则以双指中点为中心if (map.options.touchZoom !== "center") {this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));}// 记录初始距离和缩放级别this._startDist = p1.distanceTo(p2);this._startZoom = map.getZoom();this._moved = false;this._zooming = true;// 停止地图当前动画map._stop();// 绑定文档级触摸事件DomEvent.on(document, "touchmove", this._onTouchMove, this);DomEvent.on(document, "touchend touchcancel", this._onTouchEnd, this);DomEvent.preventDefault(e); // 阻止默认行为},_onTouchMove: function (e) {// 计算当前两指距离,计算缩放比例if (!e.touches || e.touches.length !== 2 || !this._zooming) {return;}var map = this._map,p1 = map.mouseEventToContainerPoint(e.touches[0]),p2 = map.mouseEventToContainerPoint(e.touches[1]),scale = p1.distanceTo(p2) / this._startDist;// 根据比例计算目标缩放级别this._zoom = map.getScaleZoom(scale, this._startZoom);// 处理缩放限制(若不允许回弹,则强制限制在min/max)if (!map.options.bounceAtZoomLimits &&((this._zoom < map.getMinZoom() && scale < 1) ||(this._zoom > map.getMaxZoom() && scale > 1))) {this._zoom = map._limitZoom(this._zoom);}// 根据模式计算新的中心点if (map.options.touchZoom === "center") {this._center = this._startLatLng;if (scale === 1) {return;}} else {// 计算双指中点偏移量,重新投影到目标缩放级别下的坐标var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);if (scale === 1 && delta.x === 0 && delta.y === 0) {return;}this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta),this._zoom);}// 触发地图移动(若未移动过,先触发`_moveStart`方法)if (!this._moved) {map._moveStart(true, false);this._moved = true;}// 使用动画帧优化性能,平滑更新地图视图Util.cancelAnimFrame(this._animRequest);var moveFn = Util.bind(map._move,map,this._center,this._zoom,{ pinch: true, round: false },undefined);this._animRequest = Util.requestAnimFrame(moveFn, this, true);DomEvent.preventDefault(e);},_onTouchEnd: function () {// 若未移动或未在缩放状态,则直接返回if (!this._moved || !this._zooming) {this._zooming = false;return;}// 清理状态和事件监听this._zooming = false;Util.cancelAnimFrame(this._animRequest);DomEvent.off(document, "touchmove", this._onTouchMove, this);DomEvent.off(document, "touchend touchcancel", this._onTouchEnd, this);// 根据配置执行最终缩放动画或直接重置视图if (this._map.options.zoomAnimation) {this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),true,this._map.options.zoomSnap);} else {this._map._resetView(this._center, this._map._limitZoom(this._zoom));}},
});Map.addInitHook("addHandler", "touchZoom", TouchZoom);

源码详解

  1. 全局配置

    • touchZoom:根据浏览器是否支持触摸事件启用功能
    • bounceAtZoomLimits:当缩放到最小/最大级别时是否允许短暂回弹(类似惯性效果)
  2. 处理器定义(TouchZoom)

    • addHooks​​: 绑定 touchstart 事件到 _onTouchStart
    • ​​removeHooks​​: 清理操作,确保处理器禁用时解除绑定。
  3. 触摸开始(_onTouchStart)

    • 仅处理双指触摸
    • 根据配置(touchZoom模式)计算缩放中心点
      • center模式:始终以地图中心缩放
      • center模式:以双指中点为中心
    • 记录初始距离和缩放级别,为后续计算缩放比例做准备
    • 绑定文档级事件,确保触摸点在移动时仍能触发
  4. 触摸移动(_onTouchMove)

    • 计算缩放比例:通过两指距离变化(scale)计算新的缩放级别
    • 处理缩放限制:若bounceAtZoomLimitsfalse,则强制限制在min/max级别
    • 计算中心点:
      • center模式:保持地图中心不变
      • center模式:根据双指中点偏移量(delta)重新投影到目标缩放级别下的坐标
    • 优化渲染:使用requestAnimFrame避免频繁更新导致的卡顿
  5. 触摸结束(_onTouchEnd)

    • 状态清理:取消动画帧,解除事件监听
    • 应用最终视图:
      • 如果启用缩放动画,平滑过渡到目标缩放级别
      • 否则直接重置视图
  6. 注册处理器
    通过Map.addInitHook方法将TouchZoom处理器添加到地图的初始化流程中,当在触摸设备上时,会实例化TouchZoom类,使其生效。

总结

  1. ​ 双指中心点计算 ​​:

    • 支持两种模式:固定地图中心或动态跟随双指中点。
    • 动态模式下,通过 projectunproject 方法处理不同缩放级别的坐标转换。
  2. 性能优化 ​​:

    • 使用 requestAnimFrame 避免过度渲染。
    • 仅在必要时触发 _moveStart_move,减少计算量。
  3. ​ 边界处理 ​​:

    • 根据 bounceAtZoomLimits 决定是否允许短暂超出缩放限制。
    • 最终缩放级别会通过 _limitZoom 确保在合法范围内。
      ​​
  4. 事件协作 ​​:
    与 Leaflet 内部方法(如_stop, _animateZoom)协作,确保与其他操作(如拖拽、其他缩放控件)互不冲突。

这段代码实现了流畅的触摸缩放交互,是 Leaflet 在移动端的重要功能之一。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com