How to Create Pulsing Location Markers on Maps

How to Create Pulsing Location Markers on Maps

Pulsing location markers create eye-catching animations that draw attention to specific locations on maps. Whether you're highlighting important destinations, showing current locations, or creating engaging interactive maps, pulsing markers add visual interest and guide user attention.

In this guide, we'll explore how to create pulsing location markers using CSS animations and SVG.

Why Use Pulsing Markers?

Pulsing markers offer several benefits:

Generate vector dotted maps

Create vector dotted maps with custom options and download them as SVG or PNG files

CSS Animation Approach

Basic Pulse Animation

.location-marker {
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.7;
    transform: scale(1.2);
  }
}

Pulse with Shadow

.location-marker {
  animation: pulseShadow 2s ease-in-out infinite;
  filter: drop-shadow(0 0 10px rgba(239, 68, 68, 0.5));
}

@keyframes pulseShadow {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
    filter: drop-shadow(0 0 10px rgba(239, 68, 68, 0.5));
  }
  50% {
    opacity: 0.8;
    transform: scale(1.3);
    filter: drop-shadow(0 0 20px rgba(239, 68, 68, 0.8));
  }
}

Generate vector dotted maps

Create vector dotted maps with custom options and download them as SVG or PNG files

SVG Circle Marker

Simple Circle Pulse

<svg class="map">
  <circle class="marker-pulse" cx="100" cy="200" r="8" fill="#ef4444" />
</svg>
.marker-pulse {
  animation: pulseCircle 2s ease-in-out infinite;
}

@keyframes pulseCircle {
  0%, 100% {
    r: 8;
    opacity: 1;
  }
  50% {
    r: 12;
    opacity: 0.6;
  }
}

Multiple Pulse Rings

<svg class="map">
  <g class="pulsing-marker">
    <circle class="pulse-ring ring-1" cx="100" cy="200" r="8" fill="none" stroke="#ef4444" />
    <circle class="pulse-ring ring-2" cx="100" cy="200" r="8" fill="none" stroke="#ef4444" />
    <circle class="pulse-ring ring-3" cx="100" cy="200" r="8" fill="none" stroke="#ef4444" />
    <circle class="marker-core" cx="100" cy="200" r="6" fill="#ef4444" />
  </g>
</svg>
.pulse-ring {
  stroke-width: 2;
  opacity: 0;
}

.ring-1 {
  animation: pulseRing 2s ease-out infinite;
}

.ring-2 {
  animation: pulseRing 2s ease-out 0.5s infinite;
}

.ring-3 {
  animation: pulseRing 2s ease-out 1s infinite;
}

.marker-core {
  fill: #ef4444;
}

@keyframes pulseRing {
  0% {
    r: 8;
    opacity: 0.8;
  }
  100% {
    r: 30;
    opacity: 0;
  }
}

Pin Marker Pulse

SVG Pin Animation

<svg class="map">
  <g class="pulsing-pin">
    <circle class="pulse-circle" cx="100" cy="180" r="15" fill="#ef4444" opacity="0.3" />
    <path class="pin-shape" d="M100,200 L105,210 L95,210 Z" fill="#ef4444" />
    <circle class="pin-dot" cx="100" cy="200" r="6" fill="#fff" />
  </g>
</svg>
.pulsing-pin {
  transform-origin: 100px 200px;
}

.pulse-circle {
  animation: pulseCircle 2s ease-in-out infinite;
}

.pin-shape {
  animation: pulsePin 2s ease-in-out infinite;
}

.pin-dot {
  animation: pulseDot 2s ease-in-out infinite;
}

@keyframes pulseCircle {
  0%, 100% {
    r: 15;
    opacity: 0.3;
  }
  50% {
    r: 25;
    opacity: 0.1;
  }
}

@keyframes pulsePin {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}

@keyframes pulseDot {
  0%, 100% {
    r: 6;
  }
  50% {
    r: 8;
  }
}

Advanced Techniques

Staggered Pulse

const markers = document.querySelectorAll('.location-marker');
markers.forEach((marker, index) => {
  marker.style.animationDelay = `${index * 0.3}s`;
});
.location-marker {
  animation: pulse 2s ease-in-out infinite;
}

Conditional Pulse

function pulseMarker(marker, condition) {
  if (condition) {
    marker.classList.add('pulsing');
  } else {
    marker.classList.remove('pulsing');
  }
}

// Example: Pulse only active locations
document.querySelectorAll('.location-marker').forEach(marker => {
  const isActive = marker.dataset.active === 'true';
  pulseMarker(marker, isActive);
});

Interactive Pulse

document.querySelectorAll('.location-marker').forEach(marker => {
  marker.addEventListener('mouseenter', () => {
    marker.style.animation = 'pulse 0.5s ease-in-out infinite';
  });
  
  marker.addEventListener('mouseleave', () => {
    marker.style.animation = 'pulse 2s ease-in-out infinite';
  });
});

Performance Optimization

Use Transform and Opacity

/* Good - GPU accelerated */
.marker {
  transform: scale(1);
  opacity: 1;
  animation: pulse 2s infinite;
}

/* Avoid - triggers layout */
.marker {
  width: 20px;
  height: 20px;
  animation: pulse 2s infinite;
}

Will-Change Property

.marker {
  will-change: transform, opacity;
  animation: pulse 2s infinite;
}

/* Remove after animation if not needed */
.marker.paused {
  will-change: auto;
}

Reduce Motion

@media (prefers-reduced-motion: reduce) {
  .marker {
    animation: none;
  }
}

Best Practices

Timing

Visual Design

Performance

Common Patterns

Single Important Marker

Multiple Active Markers

Status-Based Pulse

Final Thoughts

Creating pulsing location markers adds engaging visual effects that draw attention to important locations on maps. Whether using simple CSS animations or complex SVG effects, pulsing markers create professional, eye-catching animations.

Start with a clean map design, add pulsing markers with appropriate timing and styling, and ensure good performance. The result is engaging map animations that guide user attention and add visual interest.

Ready to add pulsing markers? Generate your dotted map and start creating pulsing location animations today.