zjk
2026-07-29 429208957f30ab9eedc5533a81aaa284048d09f5
src/robotaxi/pages/share-trip/hooks/use-vehicle-tracking.ts
@@ -128,48 +128,50 @@
            }
        };
        // 兜底定时器,防止回调丢失导致动画队列卡死
        fallbackTimer = setTimeout(() => {
            finishTranslate();
        }, TRANSLATE_DURATION_MS + 50);
    // 兜底定时器,防止回调丢失导致动画队列卡死
    fallbackTimer = setTimeout(() => {
      finishTranslate();
    }, task.duration + 50);
        Taro.nextTick(() => {
            const mapCtx = Taro.createMapContext('map');
            mapCtx.translateMarker({
                markerId: task.markerId,
                destination: {
                    latitude: task.latitude,
                    longitude: task.longitude,
                },
                autoRotate: false,
                moveWithRotate: true,
                rotate: task.rotate,
                duration: Math.max(task.duration, 100),
                animationEnd: () => {
                    if (translateSessionId !== translateSessionIdRef.current) {
                        return;
                    }
                    lastAppliedTranslateTaskRef.current = {
                        latitude: task.latitude,
                        longitude: task.longitude,
                        rotate: task.rotate
                    };
                    finishTranslate();
                },
                fail: () => {
                    if (translateSessionId !== translateSessionIdRef.current) {
                        return;
                    }
                    lastAppliedTranslateTaskRef.current = {
                        latitude: task.latitude,
                        longitude: task.longitude,
                        rotate: task.rotate
                    };
                    finishTranslate();
                }
            });
        });
    };
    Taro.nextTick(() => {
      const mapCtx = Taro.createMapContext("map");
      mapCtx.translateMarker({
        markerId: task.markerId,
        destination: {
          latitude: task.latitude,
          longitude: task.longitude,
        },
        autoRotate: false,
        moveWithRotate: true,
        rotate: task.rotate,
        // duration 为 0 时,微信地图在 iOS 存在 Bug(回调永远不触发或引发死锁)。
        // 兜底为 1ms,既能实现视觉上的"瞬移"(解决重置旋转矩阵的需求),又能保证动画队列正常结束。
        duration: Math.max(task.duration, 1),
        animationEnd: () => {
          if (translateSessionId !== translateSessionIdRef.current) {
            return;
          }
          lastAppliedTranslateTaskRef.current = {
            latitude: task.latitude,
            longitude: task.longitude,
            rotate: task.rotate,
          };
          finishTranslate();
        },
        fail: () => {
          if (translateSessionId !== translateSessionIdRef.current) {
            return;
          }
          lastAppliedTranslateTaskRef.current = {
            latitude: task.latitude,
            longitude: task.longitude,
            rotate: task.rotate,
          };
          finishTranslate();
        },
      });
    });
  };
    // 更新车辆位置并维护最近位置引用
    const updateVehicleLocationThrottled = (
@@ -234,26 +236,27 @@
    }, []);
    /**
     * 暂停 translateMarker 并切换到新的 markerId。
     * 在 CarMarker 重建期间调用:原生层即将销毁旧 marker、用 newMarkerId 创建新 marker,
     * 这里同步把 vehicleMarkerIdRef 切到新 id,pending 任务的 markerId 也一并更新,
     * 确保 ready 恢复后 translateMarker 作用于新 marker。
     *
     * 关键:保留 pendingTranslateRef.current(只改 markerId)。
     * - 若 suspend 前已有 pending(最近一次推送写入但尚未 flush),ready 恢复后会直接消费它。
     * - 若 suspend 后再有新推送,translateCar useEffect 会用最新值覆盖 pending(markerId 用 ref 取最新)。
     * 重置 translateMarker 并准备新状态。
     * 背景:为了解决旧版方案(修改 marker ID)导致的车标虚影问题,我们现已将 marker ID 固定。
     * 当需要强行纠正位置或清除原生层残留的旋转矩阵(rotate)时:
     * 我们不再销毁/重建 marker,而是将 pending 动画的 duration 设为极小值(0,实际运行为 1ms),
     * 让原生引擎立即"瞬移"到目标状态,从而强制覆盖掉内部的旧状态。
     */
    const suspendVehicleMarker = useCallback((newMarkerId: number) => {
    const suspendVehicleMarker = useCallback((_newMarkerId: number) => {
        isTranslatingRef.current = false;
        // 清除上一次的记录,让下次 translate 时认为发生了位移和角度变化,必须派发指令
        lastAppliedTranslateTaskRef.current = null;
        vehicleMarkerReadyRef.current = false;
        clearVehicleMarkerReadyTimer();
        translateSessionIdRef.current += 1;
        vehicleMarkerIdRef.current = newMarkerId;
        // 注意:不更新 vehicleMarkerIdRef.current,因为不再派生新 ID
        // 保留 pending,并将 duration 设为 0 以强制原生层立即归位(重置旋转矩阵和位置)
        if (pendingTranslateRef.current) {
            pendingTranslateRef.current = {
                ...pendingTranslateRef.current,
                markerId: newMarkerId
                duration: ROTATE_ONLY_DURATION_MS
            };
        }
    }, []);