You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps API 折线动画速度与线段长度适配问题

Fixing Consistent Speed Animation for Multiple Polylines on Google Maps

Ah, I get it—using a fixed offset increment makes longer lines animate faster because each percentage jump covers more actual distance. The key is to adjust the offset change based on each line's total length so that all lines move at the same real-world speed (like meters per second). Here's how to do it:

Step 1: Calculate Each Polyline's Total Length

First, you need to know how long each polyline is. Use Google Maps' geometry library to compute the length in meters for every line. Make sure you include the geometry library in your Maps script URL (add &libraries=geometry to the end).

Step 2: Track Per-Polyline Data

Store each line's total length and its current animation offset so you can update them individually. A Map works great for this.

Step 3: Animate Based on Time and Speed

Instead of using a fixed offset increment per frame, calculate how much distance each line should cover in the time since the last frame. Convert that distance to a percentage of the line's total length to get the offset change.

Full Code Example

// Initialize your map first (omitted for brevity)

// Create your polylines with animation symbols
const polylines = [
  new google.maps.Polyline({
    path: [{ lat: 37.7749, lng: -122.4194 }, { lat: 37.789, lng: -122.407 }],
    map: map,
    strokeColor: '#FF0000',
    icons: [{
      icon: { path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW },
      offset: '0%'
    }]
  }),
  new google.maps.Polyline({
    path: [{ lat: 37.7749, lng: -122.4194 }, { lat: 37.765, lng: -122.432 }],
    map: map,
    strokeColor: '#00FF00',
    icons: [{
      icon: { path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW },
      offset: '0%'
    }]
  })
];

// Store length and current offset for each polyline
const polylineAnimationData = new Map();
polylines.forEach(polyline => {
  const totalLength = google.maps.geometry.spherical.computeLength(polyline.getPath());
  polylineAnimationData.set(polyline, {
    totalLength: totalLength,
    currentOffset: 0
  });
});

// Set your desired speed in meters per second
const animationSpeed = 50; // 50 meters per second
let lastAnimationTimestamp = 0;

function animatePolylines(timestamp) {
  // Initialize last timestamp on first run
  if (!lastAnimationTimestamp) lastAnimationTimestamp = timestamp;
  
  // Calculate time passed since last frame (in seconds)
  const deltaTime = (timestamp - lastAnimationTimestamp) / 1000;
  
  // Update each polyline's animation
  polylineAnimationData.forEach((data, polyline) => {
    // How far should this line move in this frame?
    const distanceToMove = animationSpeed * deltaTime;
    
    // Convert distance to percentage of the line's total length
    const offsetIncrement = (distanceToMove / data.totalLength) * 100;
    
    // Update current offset
    data.currentOffset += offsetIncrement;
    
    // Reset if we've reached the end of the line
    if (data.currentOffset > 100) {
      data.currentOffset = 0; // Loop back to start, or set to 100 to stop
    }
    
    // Apply the new offset to the polyline's symbol
    const icons = polyline.get('icons');
    icons[0].offset = `${data.currentOffset}%`;
    polyline.set('icons', icons);
  });
  
  // Update last timestamp for next frame
  lastAnimationTimestamp = timestamp;
  
  // Keep the animation going
  requestAnimationFrame(animatePolylines);
}

// Start the animation loop
requestAnimationFrame(animatePolylines);

Key Notes:

  • Consistent Speed: By calculating offset based on distance per time unit, every line moves the same number of meters per second, regardless of length.
  • Geometry Library: Don't forget to include &libraries=geometry in your Google Maps API script URL—otherwise computeLength won't work.
  • Loop Control: If you don't want the animation to loop, replace the reset to 0 with setting data.currentOffset = 100 and stop the animation by canceling the requestAnimationFrame (store the ID and call cancelAnimationFrame when needed).

This approach ensures that all your polylines animate at the same real-world speed, fixing the "longer lines move faster" issue you're seeing.

内容的提问来源于stack exchange,提问作者MarvinVK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:27:52