Skip to content

Display the Globe

This example demonstrates how to display a 3D globe view with an optional animated starfield background. You can toggle the stars effect on/off using the button below.

Interactive Demo


Code Implementation

Below are two implementation examples: one with the starfield effect and one without.

Option 1: Globe with Stars Background (Full Interactive Experience)

This implementation includes:

  • Animated starfield background with multiple layers
  • Stars that rotate and move with globe interactions
  • Parallax mouse effect for depth
  • Toggle button to show/hide stars
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="stylesheet"
      href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css"
    />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>

    <style>
      body {
        margin: 0;
        padding: 0;
        background: #000;
        overflow: hidden;
      }

      #map {
        height: 100vh;
        width: 100%;
      }

      /* Toggle button */
      #toggleStars {
        position: absolute;
        z-index: 1000;
        top: 20px;
        right: 20px;
        padding: 10px 20px;
        background: rgba(0, 150, 255, 0.8);
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-weight: bold;
      }

      #toggleStars:hover {
        background: rgba(0, 150, 255, 1);
      }

      /* Stars container */
      #stars {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100vh;
        pointer-events: none;
        z-index: -1;
        overflow: hidden;
        transform-origin: center center;
        transition: transform 0.05s ease-out, opacity 0.3s ease;
      }

      #stars.hidden {
        opacity: 0;
      }

      /* Star layers - Large bright stars */
      #stars::before {
        content: '';
        position: absolute;
        top: -150%;
        left: -150%;
        width: 400%;
        height: 400%;
        background:
          radial-gradient(4px 4px at 25px 35px, #ffffff, rgba(255,255,255,0.6) 15%, transparent 60%),
          radial-gradient(3px 3px at 85px 25px, #87ceeb, rgba(135,206,235,0.7) 10%, transparent 50%),
          radial-gradient(3.5px 3.5px at 145px 75px, #fffacd, rgba(255,250,205,0.8) 8%, transparent 45%),
          radial-gradient(4px 4px at 195px 125px, #ffd700, rgba(255,215,0,0.7) 10%, transparent 50%),
          radial-gradient(3px 3px at 245px 45px, #ffa500, rgba(255,165,0,0.6) 15%, transparent 60%);
        background-repeat: repeat;
        background-size: 320px 320px;
        animation: twinkle 3s ease-in-out infinite;
      }

      /* Star layers - Small distant stars */
      #stars::after {
        content: '';
        position: absolute;
        top: -125%;
        left: -125%;
        width: 350%;
        height: 350%;
        background:
          radial-gradient(0.8px 0.8px at 20px 30px, rgba(255,255,255,0.6), transparent 70%),
          radial-gradient(0.6px 0.6px at 50px 60px, rgba(173,216,230,0.5), transparent 75%),
          radial-gradient(0.7px 0.7px at 80px 20px, rgba(255,250,205,0.6), transparent 70%),
          radial-gradient(0.5px 0.5px at 110px 80px, rgba(255,255,255,0.4), transparent 80%);
        background-repeat: repeat;
        background-size: 280px 280px;
        animation: twinkle 4s ease-in-out infinite reverse;
      }

      @keyframes twinkle {
        0% { opacity: 0.6; }
        50% { opacity: 1; }
        100% { opacity: 0.8; }
      }
    </style>
  </head>
  <body>
    <button id="toggleStars">Hide Stars</button>
    <div id="stars"></div>
    <div id="map"></div>

    <script>
      // Don't forget to replace <YOUR_ACCESS_TOKEN> by your own access token
      const accessToken = "<YOUR_ACCESS_TOKEN>";

      const map = new mapmetricsgl.Map({
        container: "map",
        style: `${accessToken}`,
        zoom: 2,
        center: [15.9150899566626, 36.25956997955441],
        attributionControl: {
          compact: false,
          position: 'bottom-right'
        }
      });

      // Once map is fully loaded, transition to globe projection
      map.on('load', () => {
        map.setProjection({
          type: "globe"
        });
      });

      // Toggle stars functionality
      const starsDiv = document.getElementById('stars');
      const toggleButton = document.getElementById('toggleStars');
      let starsVisible = true;

      toggleButton.addEventListener('click', () => {
        starsVisible = !starsVisible;
        if (starsVisible) {
          starsDiv.classList.remove('hidden');
          toggleButton.textContent = 'Hide Stars';
        } else {
          starsDiv.classList.add('hidden');
          toggleButton.textContent = 'Show Stars';
        }
      });

      // Stars rotation effect
      let currentRotation = 0;

      function updateStarBackground() {
        const bearing = map.getBearing() || 0;
        const pitch = map.getPitch() || 0;
        const center = map.getCenter();
        const lng = center.lng || 0;

        currentRotation = -bearing * 0.8 - pitch * 0.4 + lng * 0.5;
        starsDiv.style.transform = `rotate(${currentRotation}deg)`;
      }

      // Listen to map movement events
      map.on('rotate', updateStarBackground);
      map.on('pitch', updateStarBackground);
      map.on('move', updateStarBackground);
      map.on('drag', updateStarBackground);
      map.on('zoom', updateStarBackground);

      // Update stars every 50ms
      setInterval(updateStarBackground, 50);
    </script>
  </body>
</html>

Option 2: Simple Globe (No Stars)

This is a basic implementation without the starfield effect - just the globe:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="stylesheet"
      href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css"
    />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>

    <style>
      body {
        margin: 0;
        padding: 0;
      }
      html,
      body,
      #map {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      // Don't forget to replace <YOUR_ACCESS_TOKEN> by your own access token
      const accessToken = "<YOUR_ACCESS_TOKEN>";

      const map = new mapmetricsgl.Map({
        container: "map",
        style: `${accessToken}`,
        zoom: 2,
        center: [15.9150899566626, 36.25956997955441],
        attributionControl: {
          compact: false,
          position: 'bottom-right'
        }
      });

      map.on("style.load", () => {
        map.setProjection({
          type: "globe"
        });
      });
    </script>
  </body>
</html>

Key Features Explained

Toggle Button

  • Location: Top-right corner of the map
  • Initial State: Stars are visible by default
  • Functionality: Click to show/hide the starfield background
  • Button Text: Changes between "Hide Stars" and "Show Stars"

Stars Animation

The starfield includes:

  1. Multiple Star Layers: Large bright stars, medium stars, and tiny distant stars
  2. Color Variety: White, blue, yellow, orange, and other star colors for realism
  3. Twinkling Effect: Stars gently pulse with opacity changes
  4. Interactive Rotation: Stars rotate as you move the globe
  5. Smooth Transitions: 0.3s fade effect when toggling visibility

Globe Projection

  • Uses map.setProjection({ type: "globe" }) to display Earth in 3D
  • Interactive rotation, pitch, and zoom

Customization Options

Change toggle button position:

css
#toggleStars {
  top: 20px;    /* Distance from top */
  right: 20px;  /* Distance from right */
}

Adjust star intensity:

css
#stars::before {
  opacity: 0.8; /* Reduce for dimmer stars */
}

Browser Compatibility

This example works in all modern browsers that support:

  • CSS animations
  • CSS filter effects
  • WebGL (for globe rendering)
  • ES6 JavaScript

Tested on: Chrome, Firefox, Safari, Edge