diff --git a/examples/terrain/README.md b/examples/terrain/README.md
new file mode 100644
index 00000000..0cf7cd07
--- /dev/null
+++ b/examples/terrain/README.md
@@ -0,0 +1,12 @@
+# Example: 3D Terrain
+
+Demonstrates how to add 3D terrain with react-map-gl.
+
+## Usage
+
+To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `src/app.js`, or set a `MapboxAccessToken` environment variable in the command line.
+
+```bash
+npm i
+npm run start
+```
diff --git a/examples/terrain/app.css b/examples/terrain/app.css
new file mode 100644
index 00000000..2d44013b
--- /dev/null
+++ b/examples/terrain/app.css
@@ -0,0 +1,24 @@
+body {
+ margin: 0;
+ background: #000;
+}
+#map {
+ width: 100vw;
+ height: 100vh;
+}
+
+.control-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ max-width: 320px;
+ background: #fff;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.3);
+ padding: 12px 24px;
+ margin: 20px;
+ font-size: 13px;
+ line-height: 2;
+ color: #6b6b76;
+ text-transform: uppercase;
+ outline: none;
+}
\ No newline at end of file
diff --git a/examples/terrain/index.html b/examples/terrain/index.html
new file mode 100644
index 00000000..7ccf392a
--- /dev/null
+++ b/examples/terrain/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+ react-map-gl Example
+
+
+
+
+
+
+
+
diff --git a/examples/terrain/package.json b/examples/terrain/package.json
new file mode 100644
index 00000000..aead06ce
--- /dev/null
+++ b/examples/terrain/package.json
@@ -0,0 +1,21 @@
+{
+ "scripts": {
+ "start": "webpack-dev-server --progress --hot --open",
+ "start-local": "webpack-dev-server --env.local --progress --hot --open"
+ },
+ "dependencies": {
+ "react": "^16.3.0",
+ "react-dom": "^16.3.0",
+ "react-map-gl": "^6.1.0"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.0.0",
+ "@babel/plugin-proposal-class-properties": "^7.0.0",
+ "@babel/preset-env": "^7.0.0",
+ "@babel/preset-react": "^7.0.0",
+ "babel-loader": "^8.0.0",
+ "webpack": "^4.20.0",
+ "webpack-cli": "^3.1.2",
+ "webpack-dev-server": "^3.1.0"
+ }
+}
diff --git a/examples/terrain/src/app.js b/examples/terrain/src/app.js
new file mode 100644
index 00000000..f1ff7c62
--- /dev/null
+++ b/examples/terrain/src/app.js
@@ -0,0 +1,61 @@
+import * as React from 'react';
+import {useState, useCallback} from 'react';
+import {render} from 'react-dom';
+import MapGL, {Source, Layer} from 'react-map-gl';
+
+import ControlPanel from './control-panel';
+
+const TOKEN = ''; // Set your mapbox token here
+
+const skyLayer = {
+ id: 'sky',
+ type: 'sky',
+ paint: {
+ 'sky-type': 'atmosphere',
+ 'sky-atmosphere-sun': [0.0, 0.0],
+ 'sky-atmosphere-sun-intensity': 15
+ }
+};
+
+export default function App() {
+ const [viewport, setViewport] = useState({
+ latitude: 32.6141,
+ longitude: -114.34411,
+ zoom: 14,
+ bearing: 80,
+ pitch: 80
+ });
+
+ const onMapLoad = useCallback(evt => {
+ const map = evt.target;
+ map.setTerrain({source: 'mapbox-dem', exaggeration: 1.5});
+ }, []);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
+
+export function renderToDom(container) {
+ render(, container);
+}
diff --git a/examples/terrain/src/control-panel.js b/examples/terrain/src/control-panel.js
new file mode 100644
index 00000000..bcd9c5c0
--- /dev/null
+++ b/examples/terrain/src/control-panel.js
@@ -0,0 +1,21 @@
+import * as React from 'react';
+
+function ControlPanel(props) {
+ return (
+
+
3D Terrain
+
Add 3D terrain and sky to a map.
+
+
+
+ );
+}
+
+export default React.memo(ControlPanel);
diff --git a/examples/terrain/webpack.config.js b/examples/terrain/webpack.config.js
new file mode 100644
index 00000000..78fe2a6a
--- /dev/null
+++ b/examples/terrain/webpack.config.js
@@ -0,0 +1,47 @@
+// NOTE: To use this example standalone (e.g. outside of repo)
+// delete the local development overrides at the bottom of this file
+
+// avoid destructuring for older Node version support
+const resolve = require('path').resolve;
+const webpack = require('webpack');
+
+const BABEL_CONFIG = {
+ presets: ['@babel/env', '@babel/react'],
+ plugins: ['@babel/proposal-class-properties']
+};
+
+const config = {
+ mode: 'development',
+
+ entry: {
+ app: resolve('./src/app.js')
+ },
+
+ output: {
+ library: 'App'
+ },
+
+ module: {
+ rules: [
+ {
+ // Compile ES2015 using babel
+ test: /\.js$/,
+ include: [resolve('.')],
+ exclude: [/node_modules/],
+ use: [
+ {
+ loader: 'babel-loader',
+ options: BABEL_CONFIG
+ }
+ ]
+ }
+ ]
+ },
+
+ // Optional: Enables reading mapbox token from environment variable
+ plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
+};
+
+// Enables bundling against src in this repo rather than the installed version
+module.exports = env =>
+ env && env.local ? require('../webpack.config.local')(config)(env) : config;
diff --git a/website/gatsby-config.js b/website/gatsby-config.js
index a90b9552..0b7e69e5 100644
--- a/website/gatsby-config.js
+++ b/website/gatsby-config.js
@@ -150,6 +150,12 @@ module.exports = {
image: 'images/example-draw-polygon.jpg',
componentUrl: resolve(__dirname, '../examples/draw-polygon/src/app.js'),
path: 'examples/draw-polygon'
+ },
+ {
+ title: 'Terrain',
+ image: 'images/example-terrain.jpg',
+ componentUrl: resolve(__dirname, '../examples/terrain/src/app.js'),
+ path: 'examples/terrain'
}
],
diff --git a/website/static/images/example-terrain.jpg b/website/static/images/example-terrain.jpg
new file mode 100644
index 00000000..077e14cb
Binary files /dev/null and b/website/static/images/example-terrain.jpg differ