---
title: "Custom night satellite image in a goble with space background | JavaScript maps SDK"
description: "Display Earth's night satellite imagery on a 3D globe."
---

> For AI agents: a documentation index is available at [/llms.txt](https://docs.maptiler.com/llms.txt). Markdown versions of all pages are available by appending .md to any URL.

# Custom night satellite image in a goble with space background

Use a custom map of the Earth’s satellite image at night and display it on a globe with a space background.

In this example, we’ll use a custom map (night satellite) along with the `halo` and `space` options to create the effect of the Earth seen from space. Additionally, we’ll rotate the Earth and shift the central view of the map so that the Earth appears in the lower left corner of the map area.

To make the custom map download the images from [Earth at Night](https://earthobservatory.nasa.gov/features/NightLights/page3.php) and generat the tiles using the [MapTiler Engine](https://www.maptiler.com/engine/)

### NPM module setup

```bash
npm install --save @maptiler/sdk
```

#### main.js

```js
import { Map, MapStyle, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
const map = new Map({
  container: 'map', // container's id or the HTML element in which the SDK will render the map
  style: 'YOUR_CUSTOM_MAP_ID',
  projection: "globe",
  center: [115.0293, 32.6789], // starting position [lng, lat]
  zoom: 2, // starting zoom
  geolocateControl: false,
  navigationControl: false,
  terrain: true,
    space: {
    preset: 'milkyway'
  },
  halo: true,
});

map.easeTo({
  padding: {
    right: 500, // push the visual center to the left
    top: 300, // push the globe down
  }
});

function loop() {
  requestAnimationFrame(loop);
  const currentCenter = map.getCenter();

  map.flyTo({ // create globe rotation animation
    center:[
      currentCenter.lng - 0.05,
      currentCenter.lat
    ]
  });
}

map.on('ready', async () => {

  map.setSky({
    "sky-color": "#87CEEB",
    "fog-color": "#87CEEB",
    "horizon-color": "#FFFFFF",
    "atmosphere-blend": 0.7
  });

  // polygon used to add haze / opacity to the night side of the globe
  map.addSource('world-cover', {
    'type': 'geojson',
    'data': {
      'type': 'Polygon',
      'coordinates': [
        [
          [-180, -90],
          [180, -90],
          [180, 90],
          [-180, 90],
          [-180, -90]
        ]
      ]
    }
  });

  map.addLayer({
    'id': 'global-atmosphere-tint',
    'type': 'fill',
    'source': 'world-cover', // Use the existing full-globe polygon source
    'paint': {
      // A semi-transparent atmospheric blue color
      'fill-color': 'rgba(135, 206, 235, 1)', 
      // Ensure it's always visible
      'fill-opacity': [
        'interpolate',
        ['linear'],
        ['zoom'],
        1, 0.15, // At zoom 1, opacity is 15%
        5, 0.0   // By zoom 4, opacity is 0% (fully transparent)
      ]
    }
  });
  
  loop();
});
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Custom night satellite image in a goble with space background | NPM example</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div id="map"></div>
  <script type="module" src="./main.js"></script>
</body>
</html>
```

#### style.css

```css
body {
  margin: 0;
  padding: 0;
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
```

### Basic JavaScript setup

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Globe with halo</title>
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <script src="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.umd.min.js"></script>
  <link href="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.css" rel="stylesheet" />
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>

<body>
  <div id="map"></div>
  <script>
    maptilersdk.config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
    const map = new maptilersdk.Map({
      container: 'map', // container's id or the HTML element in which the SDK will render the map
      style: 'YOUR_CUSTOM_MAP_ID',
      projection: "globe",
      center: [115.0293, 32.6789], // starting position [lng, lat]
      zoom: 2, // starting zoom
      geolocateControl: false,
      navigationControl: false,
      terrain: true,
        space: {
        preset: 'milkyway'
      },
      halo: true,
    });

    map.easeTo({
      padding: {
        right: 500, // push the visual center to the left
        top: 300, // push the globe down
      }
    });

    function loop() {
      requestAnimationFrame(loop);
      const currentCenter = map.getCenter();

      map.flyTo({ // create globe rotation animation
        center:[
          currentCenter.lng - 0.05,
          currentCenter.lat
        ]
      });
    }

    map.on('ready', async () => {

      map.setSky({
        "sky-color": "#87CEEB",
        "fog-color": "#87CEEB",
        "horizon-color": "#FFFFFF",
        "atmosphere-blend": 0.7
      });

      // polygon used to add haze / opacity to the night side of the globe
      map.addSource('world-cover', {
        'type': 'geojson',
        'data': {
          'type': 'Polygon',
          'coordinates': [
            [
              [-180, -90],
              [180, -90],
              [180, 90],
              [-180, 90],
              [-180, -90]
            ]
          ]
        }
      });

      map.addLayer({
        'id': 'global-atmosphere-tint',
        'type': 'fill',
        'source': 'world-cover', // Use the existing full-globe polygon source
        'paint': {
          // A semi-transparent atmospheric blue color
          'fill-color': 'rgba(135, 206, 235, 1)', 
          // Ensure it's always visible
          'fill-opacity': [
            'interpolate',
            ['linear'],
            ['zoom'],
            1, 0.15, // At zoom 1, opacity is 15%
            5, 0.0   // By zoom 4, opacity is 0% (fully transparent)
          ]
        }
      });
      
      loop();
    });
  </script>
</body>

</html>
```

## Learn more

For halo customization, check the [RadialGradientLayerConstructorOptions](https://docs.maptiler.com/sdk-js/api/types/#RadialGradientLayerConstructorOptions).

## Related examples

### [Globe with halo](https://docs.maptiler.com/sdk-js/examples/halo-simple/)

Examples

Add a simulated atmospheric glow around the 3D globe.

### [Globe with milkyway and stars](https://docs.maptiler.com/sdk-js/examples/space-milkyway/)

Examples

Add a milkyway and stars background to the globe.

### [Globe with milkyway and halo](https://docs.maptiler.com/sdk-js/examples/space-milkyway-halo/)

Examples

Add a red Milky Way and halo to the globe.

### [Globe projection](https://docs.maptiler.com/sdk-js/examples/globe-projection/)

Examples

Enable the 3D globe map projection in your application.
