---
title: "Add dynamic hillshading | JavaScript maps SDK"
description: "Adjust hillshade lighting dynamically to simulate sun movement."
---

> 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.

# Add dynamic hillshading

Changes in lightning of hills and mountains can easily simulate the movement of the sun during the day. You can achieve this by changing the [paint properties](https://docs.maptiler.com/gl-style-specification/layers/#hillshade) of the “Hillshade” layer from [MapTiler Terrain RGB](https://docs.maptiler.com/guides/map-tiling-hosting/data-hosting/rgb-terrain-by-maptiler/), which is included in Outdoor map style. Here is an [example how to add a hillshading layer](https://docs.maptiler.com/sdk-js/api/layers/#hillshade) to any map style.

If you do not need dynamic lighting, you can add and [set hillshading values](https://docs.maptiler.com/guides/map-design/layer-styling/#raster-styling) directly in the MapTiler Map Designer tool.

### 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';

// Function to update hillshade layer properties based on UI controls
const update = function () {
  const bw = document.getElementById('bw').checked;
  const paint = {
    // Get values from sliders and checkbox
    "hillshade-illumination-direction": parseFloat(document.getElementById('dir').value),
    "hillshade-exaggeration": parseFloat(document.getElementById('exa').value),
    // Set colors based on B&W checkbox
    "hillshade-highlight-color": bw ? '#FFFFFF' : 'hsla(141, 35%, 47%, 0.75)',
    "hillshade-shadow-color": bw ? '#000000' : 'hsla(130, 43%, 11%, 0.9)',
    "hillshade-accent-color": bw ? '#000000' : '#dcf193'
  };

  // Apply paint properties to the 'Hillshade' layer
  Object.keys(paint).forEach(function (key) {
    map.setPaintProperty('Hillshade', key, paint[key]);
  });
};

const mapId = MapStyle.OUTDOOR;
// Set MapTiler API key
config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
// Initialize the map
const map = new Map({
  container: 'map',
  zoom: 8,
  center: [9.0144, 46.5664],
  style: mapId
});

// Update hillshade layer once the map style is loaded
map.once('styledata', function () {
  update();
});
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Add dynamic hillshading | NPM example</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <!-- Control panel for hillshade options -->
  <div class="map-options">
    Direction: <br>
    <!-- Slider to control illumination direction -->
    <input type="range" min="0" max="359" value="335" oninput="update()" id="dir" /> <br>
    Exaggeration: <br>
    <!-- Slider to control hillshade exaggeration -->
    <input type="range" min="0" max="1" value="0.4" step="0.05" oninput="update()" id="exa" /> <br>
    <!-- Checkbox to toggle black & white mode -->
    B&amp;W: <input type="checkbox" onchange="update()" id="bw" /> <br>
  </div>
  <!-- Map container -->
  <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%;
}

/* Style for the map options control panel */
.map-options {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 5px 10px;
  font-size: 12px;
  z-index: 85;
  background: #fff;
  border-radius: 4px;
  opacity: 0.9;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
  white-space: nowrap;
}
```

### Basic JavaScript setup

```html
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Create dynamic hillshade</title>
  <!-- Load MapTiler SDK JS and CSS -->
  <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 for the map options control panel */
    .map-options {
      position: absolute;
      top: 10px;
      left: 10px;
      padding: 5px 10px;
      font-size: 12px;
      z-index: 85;
      background: #fff;
      border-radius: 4px;
      opacity: 0.9;
      box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
      white-space: nowrap;
    }
  </style>
</head>

<body>
  <!-- Control panel for hillshade options -->
  <div class="map-options">
    Direction: <br>
    <!-- Slider to control illumination direction -->
    <input type="range" min="0" max="359" value="335" oninput="update()" id="dir" /> <br>
    Exaggeration: <br>
    <!-- Slider to control hillshade exaggeration -->
    <input type="range" min="0" max="1" value="0.4" step="0.05" oninput="update()" id="exa" /> <br>
    <!-- Checkbox to toggle black & white mode -->
    B&amp;W: <input type="checkbox" onchange="update()" id="bw" /> <br>
  </div>
  <!-- Map container -->
  <div id="map"></div>
  <script>
    // Function to update hillshade layer properties based on UI controls
    const update = function () {
      const bw = document.getElementById('bw').checked;
      const paint = {
        // Get values from sliders and checkbox
        "hillshade-illumination-direction": parseFloat(document.getElementById('dir').value),
        "hillshade-exaggeration": parseFloat(document.getElementById('exa').value),
        // Set colors based on B&W checkbox
        "hillshade-highlight-color": bw ? '#FFFFFF' : 'hsla(141, 35%, 47%, 0.75)',
        "hillshade-shadow-color": bw ? '#000000' : 'hsla(130, 43%, 11%, 0.9)',
        "hillshade-accent-color": bw ? '#000000' : '#dcf193'
      };

      // Apply paint properties to the 'Hillshade' layer
      Object.keys(paint).forEach(function (key) {
        map.setPaintProperty('Hillshade', key, paint[key]);
      });
    };

    const mapId = maptilersdk.MapStyle.OUTDOOR;
    // Set MapTiler API key
    maptilersdk.config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
    // Initialize the map
    const map = new maptilersdk.Map({
      container: 'map',
      zoom: 8,
      center: [9.0144, 46.5664],
      style: mapId
    });

    // Update hillshade layer once the map style is loaded
    map.once('styledata', function () {
      update();
    });
  </script>
</body>

</html>
```

## Related examples

### [Add hillshading](https://docs.maptiler.com/sdk-js/examples/hillshade/)

Examples

Add raster hillshading effect to a MapTiler map.

### [3D terrain map](https://docs.maptiler.com/sdk-js/examples/3d-map/)

Tutorials

Create and display 3D terrain maps on web pages.

### [Raster layer](https://docs.maptiler.com/sdk-js/examples/raster-layer/)

Tutorials

Add a raster image overlay to the map.
