forked from zhouruizhe/gmTouringMiniApp
AI Code Review / review (pull_request) Successful in 2m11s
选中标点后地图在左右/上下反复抽动,根因是视口回写形成了自激回路: map 的 longitude/latitude/scale 绑定到 store,而 regionchange 又无条件把 地图当前中心点写回 store —— 写 store 触发地图移动,移动结束回传一个 「差一点点」的中心点,再写回,再移动。上一个提交把中心点改成从 detail.centerLocation 同步读取后,回路里原本靠 getCenterLocation 异步跳变 掩盖住的这一点噪声就直接闭合了。 两道闸: - 只接受手势造成的变化。causedBy 为 update(我们自己改绑定值或调 includePoints 触发)时 store 已是权威值,不回写。老基础库拿不到 causedBy 时退化到下一道闸。 - 所有回写走 commitViewport,经 isSignificantViewportChange 过滤掉小于 1e-4 度 / 0.01 级的变化。远小于任何一次真实拖动,足以吸收量化噪声。 顺带修一个 H5 构建回归(1bcdd40 引入):uni 的 H5 路由生成器按路径推导 组件标识,pages/poi/detail 与 pages-poi/detail 都归一成 PagesPoiDetail, 重复声明导致 build:h5 失败。兼容跳板必须留在旧路径上,所以改名分包路由 pages-poi/detail -> pages-poi/poi-detail。
26 lines
1.3 KiB
TypeScript
26 lines
1.3 KiB
TypeScript
import type { MapViewport } from '@/domain/poi'
|
|
|
|
/**
|
|
* 约 1e-4 度 ≈ 11 米。原生地图把中心点量化到像素,回传的中心点和我们写进去的
|
|
* 值总会差一点点;这个阈值用来吸收那点量化噪声,同时远小于任何一次真实拖动。
|
|
*/
|
|
const COORDINATE_EPSILON = 1e-4
|
|
const SCALE_EPSILON = 0.01
|
|
|
|
/**
|
|
* 判断地图回传的视口是否真的变了,值得写回 store。
|
|
*
|
|
* 地图的 longitude/latitude/scale 是绑定到 store 的,而 `regionchange` 又会把
|
|
* 地图当前中心点回写 store —— 这是一个闭环。选中标点后我们把视口设到 POI 坐标,
|
|
* 地图动画结束回传一个「差一点点」的中心点,无条件写回就会再次改动绑定值、
|
|
* 触发地图移动、再回传……表现出来就是地图在左右或上下反复抽动。
|
|
*
|
|
* 回写本身是需要的(用户拖完地图,store 要记住新位置,返回页面时才能恢复),
|
|
* 所以这里不是禁止回写,而是把小于阈值的变化当作噪声丢掉,让闭环收敛。
|
|
*/
|
|
export function isSignificantViewportChange(current: MapViewport, next: MapViewport): boolean {
|
|
return Math.abs(next.longitude - current.longitude) >= COORDINATE_EPSILON
|
|
|| Math.abs(next.latitude - current.latitude) >= COORDINATE_EPSILON
|
|
|| Math.abs(next.scale - current.scale) >= SCALE_EPSILON
|
|
}
|