---
title: "3D model set the roll | 3D JS | JavaScript maps SDK"
description: "Rotate 3D models by setting the roll property."
---

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

# 3D model set the roll

Use the [MapTiler 3D JS module](https://docs.maptiler.com/sdk-js/modules/3d/) to rotate a 3D model, setting the roll property. Roll the model on its central axis. Indicate the rotation angle in degrees. Thanks to the 3D JS module we can add 3D models to the map and configure it as we want, rotating it, animating it, scaling it, etc.

[Model credit](#fn:1)

### NPM module setup

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

#### main.js

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

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

const center = [2.3492790851936776, 48.85417501375531];

const map = new Map({
  container: document.getElementById('map'),
  hash: true,
  style: MapStyle.DATAVIZ.DARK,
  zoom: 11,
  center: [2.4444, 48.8785],
  pitch: 77,
  bearing: 44,
  maxPitch: 85,
  terrainControl: true,
  terrain: true,
  maptilerLogo: true,
});

(async () => {
  await map.onReadyAsync();

  const layer3D = new Layer3D("custom-3D-layer");
  map.addLayer(layer3D);

  const LNGLAT_OFFSET = 0.25;
  const PLANE_BASE_ALT = 2200;

  // Adding a point light
  layer3D.addPointLight("point-light", {
    intensity: 20,
    color: "#ffffff",
    lngLat: center.map(num => num + 0.0001),
    altitude: 2000,
    altitudeReference: AltitudeReference.GROUND,
  });

  // Adding a mesh of a plane. 
  const originalPlaneID = "biplaneOne";
  const biplaneOne = await layer3D.addMeshFromURL(
    originalPlaneID,
    "https://docs-media.maptiler.com/docs/models/low_poly_biplane.glb",
    {
      lngLat: center,
      heading: 0,
      scale: 300,
      altitude: PLANE_BASE_ALT,
      altitudeReference: AltitudeReference.GROUND,
      transform: {
        rotation: {
          y: Math.PI / 2,
        },
      }
    }
  );

  layer3D.cloneMesh("biplaneOne", "biplaneTwo");
  layer3D.cloneMesh("biplaneOne", "biplaneThree");
  layer3D.cloneMesh("biplaneOne", "biplaneFour");
  layer3D.cloneMesh("biplaneOne", "biplaneFive");
  const biplaneTwo = layer3D.getItem3D("biplaneTwo");
  biplaneTwo.setLngLat([center[0]+0.05, center[1]]);
  biplaneTwo.setRoll(45);
  const biplaneThree = layer3D.getItem3D("biplaneThree");
  biplaneThree.setLngLat([center[0]+(0.05*2), center[1]]);
  biplaneThree.setRoll(120);
  const biplaneFour = layer3D.getItem3D("biplaneFour");
  biplaneFour.setLngLat([center[0]+(0.05*3), center[1]]);
  biplaneFour.setRoll(-45);
  const biplaneFive = layer3D.getItem3D("biplaneFive");
  biplaneFive.setLngLat([center[0]+(0.05*4), center[1]]);
  biplaneFive.setRoll(-90);

})()
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>3D model set the roll | 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
<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>Add a 3D model</title>
<script src="https://cdn.jsdelivr.net/npm/lil-gui@0.19"></script>
<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" />
<!-- Importing MapTiler 3D js -->
<script src="https://cdn.maptiler.com/maptiler-3d/v4.0.1/maptiler-3d.umd.min.js"></script>
<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 center = [2.3492790851936776, 48.85417501375531];

  const map = new maptilersdk.Map({
    container: document.getElementById('map'),
    hash: true,
    style: maptilersdk.MapStyle.DATAVIZ.DARK,
    zoom: 11,
    center: [2.4444, 48.8785],
    pitch: 77,
    bearing: 44,
    maxPitch: 85,
    terrainControl: true,
    terrain: true,
    maptilerLogo: true,
  });

  (async () => {
    await map.onReadyAsync();

    const layer3D = new maptiler3d.Layer3D("custom-3D-layer");
    map.addLayer(layer3D);

    const LNGLAT_OFFSET = 0.25;
    const PLANE_BASE_ALT = 2200;

    // Adding a point light
    layer3D.addPointLight("point-light", {
      intensity: 20,
      color: "#ffffff",
      lngLat: center.map(num => num + 0.0001),
      altitude: 2000,
      altitudeReference: maptiler3d.AltitudeReference.GROUND,
    });

    // Adding a mesh of a plane. 
    const originalPlaneID = "biplaneOne";
    const biplaneOne = await layer3D.addMeshFromURL(
      originalPlaneID,
      "https://docs-media.maptiler.com/docs/models/low_poly_biplane.glb",
      {
        lngLat: center,
        heading: 0,
        scale: 300,
        altitude: PLANE_BASE_ALT,
        altitudeReference: maptiler3d.AltitudeReference.GROUND,
        transform: {
          rotation: {
            y: Math.PI / 2,
          },
        }
      }
    );

    layer3D.cloneMesh("biplaneOne", "biplaneTwo");
    layer3D.cloneMesh("biplaneOne", "biplaneThree");
    layer3D.cloneMesh("biplaneOne", "biplaneFour");
    layer3D.cloneMesh("biplaneOne", "biplaneFive");
    const biplaneTwo = layer3D.getItem3D("biplaneTwo");
    biplaneTwo.setLngLat([center[0]+0.05, center[1]]);
    biplaneTwo.setRoll(45);
    const biplaneThree = layer3D.getItem3D("biplaneThree");
    biplaneThree.setLngLat([center[0]+(0.05*2), center[1]]);
    biplaneThree.setRoll(120);
    const biplaneFour = layer3D.getItem3D("biplaneFour");
    biplaneFour.setLngLat([center[0]+(0.05*3), center[1]]);
    biplaneFour.setRoll(-45);
    const biplaneFive = layer3D.getItem3D("biplaneFive");
    biplaneFive.setLngLat([center[0]+(0.05*4), center[1]]);
    biplaneFive.setRoll(-90);

  })()
</script>
</body>
</html>
```

[Low-Poly Biplane](https://skfb.ly/oG9qS) by ElectrikGoat0395 is licensed under [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/) [↩](#fnref:1)

## Related examples

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

Examples

Rotate 3D models by setting the pitch tilt property.

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

Examples

Listen for mouse events on 3D models in maps.

### [3D model pitch and roll](https://docs.maptiler.com/sdk-js/examples/3d-js-roll-pitch/)

Examples

Rotate 3D models using pitch and roll properties.

### [Animate a 3D model](https://docs.maptiler.com/sdk-js/examples/3d-js-animated/)

Examples

Animate 3D models and display them on a map.
