Skip to content

路径行走动画

上次更新 2025年8月20日星期三 3:16:20 字数 0 字 时长 0 分钟

示例

TIP

本示例展示了如何在 Leaflet 地图上创建一个沿指定路径移动的标记动画。主要实现了以下功能:

  • 定义一系列路径坐标点
  • 创建路径线条显示完整路径
  • 创建一个自定义图标的标记
  • 实现标记沿路径平滑移动的动画效果

新标签页预览

代码实现

vue
<template>
  <div id="map" class="w-full h-96"></div>
</template>

<script setup>
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import { onMounted, ref } from "vue";

const map = ref(null);

onMounted(() => {
  const urlLayer =
    "http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=d32c6748c80f81a44acd8633cea41dfd";

  map.value = L.map("map", {
    center: [39.09361883285121, 117.22686767578126], // 天津
    zoom: 12,
    zoomControl: true,
    doubleClickZoom: false,
    attributionControl: false,
  });

  // 底图
  const baseLayer = L.tileLayer(urlLayer).addTo(map.value);

  // 定义路径点
  const pathCoordinates = [
    [39.084899, 117.20083], // 起点(左下角)
    [39.104899, 117.20083], // 左下到左上
    [39.104899, 117.25083], // 左上到右上
    [39.084899, 117.25083], // 右上到右下
    [39.086899, 117.23083], // 右下往左
    [39.102899, 117.23083], // 向上
    [39.102899, 117.22083], // 向左
    [39.088899, 117.22083], // 向下
    [39.088899, 117.21083], // 继续向下
    [39.094899, 117.21083], // 终点
  ];

  // 创建路径线
  const pathLine = L.polyline(pathCoordinates, {
    color: "blue",
    weight: 3,
  }).addTo(map.value);

  // 创建移动的标记
  const marker = L.marker(pathCoordinates[0], {
    icon: L.icon({
      iconUrl: "./icon.svg",
    }),
  }).addTo(map.value);

  // 动画函数
  let i = 0;
  function animate(duration = 2000, frames = 120) {
    // 平均时间恒定
    const avgTime = duration / (pathCoordinates.length - 1) / frames;

    if (i < pathCoordinates.length - 1) {
      // 计算两点之间的插值
      const start = L.latLng(pathCoordinates[i]);
      const end = L.latLng(pathCoordinates[i + 1]);
      let frame = 0;

      const animateInterval = setInterval(() => {
        frame++;
        const progress = frame / frames;

        const lat = start.lat + (end.lat - start.lat) * progress;
        const lng = start.lng + (end.lng - start.lng) * progress;

        marker.setLatLng([lat, lng]);

        if (frame === frames) {
          clearInterval(animateInterval);
          i++;
          animate();
        }
      }, avgTime);
    }
  }

  // 开始动画
  animate(1000);
});
</script>
关注公众号