diff --git a/examples/get-started/pure-js/arcgis-globe/README.md b/examples/get-started/pure-js/arcgis-globe/README.md
new file mode 100644
index 000000000000..990fb9d141f0
--- /dev/null
+++ b/examples/get-started/pure-js/arcgis-globe/README.md
@@ -0,0 +1,23 @@
+
+
![](https://webpack.js.org/assets/icon-square-big.svg)
+
+
+## Example: Use deck.gl with Esri ArcGIS API for JavaScript
+
+This sample shows how to use the `@deck.gl/arcgis` module to add a deck.gl layer to an [ArcGIS JavaScript](https://developers.arcgis.com/javascript/) app.
+Uses [Webpack](https://github.com/webpack/webpack) and the [ArcGIS Webpack plugin](https://github.com/Esri/arcgis-webpack-plugin)
+to bundle files and serves it with [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server).
+
+## Usage
+
+To install dependencies:
+
+```bash
+npm install
+# or
+yarn
+```
+
+Commands:
+* `npm start` is the development target, to serve the app and hot reload.
+* `npm run build` is the production target, to create the final bundle and write to disk.
diff --git a/examples/get-started/pure-js/arcgis-globe/app.js b/examples/get-started/pure-js/arcgis-globe/app.js
new file mode 100644
index 000000000000..e999dc995350
--- /dev/null
+++ b/examples/get-started/pure-js/arcgis-globe/app.js
@@ -0,0 +1,78 @@
+import {loadArcGISModules} from '@deck.gl/arcgis';
+import {GeoJsonLayer, ArcLayer} from '@deck.gl/layers';
+import {_GlobeView as GlobeView} from '@deck.gl/core';
+
+// source: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz
+const AIR_PORTS =
+ 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_airports.geojson';
+
+loadArcGISModules(['esri/Map', 'esri/views/SceneView', 'esri/views/3d/externalRenderers']).then(
+ ({DeckRenderer, modules}) => {
+ const [ArcGISMap, SceneView, externalRenderers] = modules;
+
+ // In the ArcGIS API for JavaScript the SceneView is responsible
+ // for displaying a Map, which usually contains at least a basemap.
+ // eslint-disable-next-line
+ const sceneView = new SceneView({
+ container: 'viewDiv',
+ map: new ArcGISMap({
+ basemap: 'dark-gray-vector',
+ layers: []
+ }),
+ center: [0.119167, 52.205276],
+ zoom: 5,
+ // disable sun
+ environment: {
+ lighting: {
+ date: new Date('null')
+ }
+ }
+ });
+
+ const renderer = new DeckRenderer(sceneView, {
+ getTooltip: info => info.object && info.object.properties.name,
+ layers: [
+ new GeoJsonLayer({
+ id: 'airports',
+ data: AIR_PORTS,
+ // Styles
+ filled: true,
+ pointRadiusMinPixels: 2,
+ pointRadiusScale: 2000,
+ getRadius: f => 11 - f.properties.scalerank,
+ getFillColor: [200, 0, 80, 180],
+ // Interactive props
+ pickable: true,
+ autoHighlight: true,
+ onClick: info =>
+ info.object &&
+ // eslint-disable-next-line
+ alert(`${info.object.properties.name} (${info.object.properties.abbrev})`)
+ }),
+ new ArcLayer({
+ id: 'arcs',
+ data: AIR_PORTS,
+ dataTransform: d => d.features.filter(f => f.properties.scalerank < 4),
+ // Styles
+ getSourcePosition: f => [-0.4531566, 51.4709959], // London
+ getTargetPosition: f => f.geometry.coordinates,
+ getSourceColor: [0, 128, 200],
+ getTargetColor: [200, 0, 80],
+ getWidth: 1
+ }),
+ new GeoJsonLayer({
+ id: 'land',
+ data: 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_land.geojson',
+ filled: false,
+ getLineColor: [255, 255, 255, 127],
+ getLineWidth: 1,
+ lineWidthUnits: 'pixels'
+ })
+ ]
+ });
+ externalRenderers.add(sceneView, renderer);
+ renderer.deckInstance.setProps({
+ views: [new GlobeView()]
+ });
+ }
+);
diff --git a/examples/get-started/pure-js/arcgis-globe/index.html b/examples/get-started/pure-js/arcgis-globe/index.html
new file mode 100644
index 000000000000..9a1dc6259e93
--- /dev/null
+++ b/examples/get-started/pure-js/arcgis-globe/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+ deck.gl w/ Esri ArcGIS API for JavaScript example
+
+
+
+
+
+
+
+
diff --git a/examples/get-started/pure-js/arcgis-globe/package.json b/examples/get-started/pure-js/arcgis-globe/package.json
new file mode 100644
index 000000000000..927748ad2883
--- /dev/null
+++ b/examples/get-started/pure-js/arcgis-globe/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "pure-js-esri-arcgis-globe",
+ "version": "0.0.0",
+ "license": "MIT",
+ "scripts": {
+ "start": "webpack-dev-server --progress --hot --open",
+ "start-local": "webpack-dev-server --env.local --progress --hot --open",
+ "build": "webpack -p"
+ },
+ "dependencies": {
+ "@deck.gl/arcgis": "^8.1.0",
+ "@deck.gl/core": "^8.1.0",
+ "@deck.gl/layers": "^8.1.0"
+ },
+ "devDependencies": {
+ "webpack": "^4.20.2",
+ "webpack-cli": "^3.1.2",
+ "webpack-dev-server": "^3.1.1"
+ }
+}
diff --git a/examples/get-started/pure-js/arcgis-globe/webpack.config.js b/examples/get-started/pure-js/arcgis-globe/webpack.config.js
new file mode 100644
index 000000000000..0bacc22fac40
--- /dev/null
+++ b/examples/get-started/pure-js/arcgis-globe/webpack.config.js
@@ -0,0 +1,13 @@
+// NOTE: To use this example standalone (e.g. outside of deck.gl repo)
+// delete the local development overrides at the bottom of this file
+
+const CONFIG = {
+ mode: 'development',
+
+ entry: {
+ app: './app.js'
+ }
+};
+
+// This line enables bundling against src in this repo rather than installed module
+module.exports = env => (env ? require('../../../webpack.config.local')(CONFIG)(env) : CONFIG);
diff --git a/modules/arcgis/src/deck-renderer.js b/modules/arcgis/src/deck-renderer.js
index 5bd62b59f602..8d1679421868 100644
--- a/modules/arcgis/src/deck-renderer.js
+++ b/modules/arcgis/src/deck-renderer.js
@@ -2,6 +2,9 @@
import {initializeResources, render, finalizeResources} from './commons';
+// ArcGIS Earth radius
+const EARTH_RADIUS = 6378137;
+
// ArcGIS fov is corner-to-corner
function arcgisFOVToDeckAltitude(fov, aspectRatio) {
const D = Math.sqrt(1 + aspectRatio ** 2);
@@ -36,18 +39,39 @@ export default function createDeckRenderer(DeckProps, externalRenderers) {
render(context) {
const [width, height] = this.view.size;
- render.call(this, {
- gl: context.gl,
- width,
- height,
- viewState: {
+ let viewState;
+ if (this.view.viewingMode === 'global') {
+ const altitude = this.view.camera.position.z / EARTH_RADIUS; // TODO
+ const zoom = EARTH_RADIUS / this.view.camera.position.z;
+ const zoom2 = Math.log2(zoom + 1); // TODO
+ console.log(this.view.camera.position.z, altitude, zoom, zoom2); // eslint-disable-line
+
+ viewState = {
+ latitude: this.view.center.latitude, // TODO: compute from this.view.camera.y, to support tilt?
+ longitude: this.view.center.longitude, // TODO: compute from this.view.camera.x, to support tilt?
+ altitude,
+ zoom: zoom2,
+ bearing: this.view.camera.heading,
+ pitch: this.view.camera.tilt
+ };
+ } else if (this.view.viewingMode === 'local') {
+ viewState = {
latitude: this.view.center.latitude,
longitude: this.view.center.longitude,
altitude: arcgisFOVToDeckAltitude(this.view.camera.fov, width / height),
zoom: this.view.zoom,
bearing: this.view.camera.heading,
pitch: this.view.camera.tilt
- }
+ };
+ } else {
+ throw new Error('Invalid state');
+ }
+
+ render.call(this, {
+ gl: context.gl,
+ width,
+ height,
+ viewState
});
}
}