ArcGIS Scene Effects
Use this skill for configuring SceneView environment, shadows, backgrounds, underground navigation, and elevation settings.
Environment Settings
Basic Environment Configuration
const view = new SceneView({ container: "viewDiv", map: scene, environment: { lighting: { directShadowsEnabled: true, date: new Date("Sun Mar 15 2019 16:00:00 GMT+0100") }, atmosphereEnabled: true, starsEnabled: true } });
Map Component Environment
<arcgis-scene item-id="YOUR_WEBSCENE_ID"> <arcgis-zoom slot="top-left"></arcgis-zoom> </arcgis-scene>
<script type="module"> const viewElement = document.querySelector("arcgis-scene"); await viewElement.viewOnReady();
viewElement.environment = { lighting: { directShadowsEnabled: true, date: new Date() }, atmosphereEnabled: true, starsEnabled: true }; </script>
Shadows and Lighting
Enable Direct Shadows
view.environment = { lighting: { directShadowsEnabled: true, date: new Date("Sun Mar 15 2019 16:00:00 GMT+0100") } };
// Update time of day dynamically function updateTimeOfDay(dateString) { view.environment.lighting.date = new Date(dateString); }
Toggle Shadows on Symbols
// Clone renderer and toggle castShadows const clone = layer.renderer.clone(); clone.symbol.symbolLayers.getItemAt(0).castShadows = true; layer.renderer = clone;
Highlight Shadow Color
import HighlightOptions from "@arcgis/core/views/support/HighlightOptions.js";
const highlightOptions = new HighlightOptions({ name: "default", color: "cyan", shadowColor: "cyan" });
view.highlights = [highlightOptions];
// Change shadow color dynamically highlightOptions.shadowColor = "#ff0000";
Virtual Lighting
view.environment = { lighting: { type: "virtual" // Consistent lighting without sun position } };
Transparent Background
Configure Transparent Background
const view = new SceneView({ container: "viewDiv", map: scene, alphaCompositingEnabled: true, // Required for transparency environment: { background: { type: "color", color: [255, 252, 244, 0] // RGBA with 0 alpha = transparent }, starsEnabled: false, atmosphereEnabled: false } });
Toggle Background Transparency
// Make background transparent const backgroundColor = view.environment.background.color.clone(); backgroundColor.a = 0; // 0 = transparent, 1 = opaque view.environment.background.color = backgroundColor;
Underground Navigation
Enable Underground Navigation (Map Component)
<arcgis-scene item-id="YOUR_WEBSCENE_ID"> <arcgis-zoom slot="top-left"></arcgis-zoom> </arcgis-scene>
<script type="module"> const viewElement = document.querySelector("arcgis-scene"); await viewElement.viewOnReady();
// Allow navigation below ground viewElement.map.ground.navigationConstraint = { type: "none" };
// Set ground opacity to see through viewElement.map.ground.opacity = 0.4;
// Optional: set surface color when no basemap viewElement.map.ground.surfaceColor = "#fff"; </script>
Underground Navigation (Core API)
const view = new SceneView({ container: "viewDiv", map: scene });
view.when(() => { // Allow camera below ground view.map.ground.navigationConstraint = { type: "none" };
// Make ground semi-transparent view.map.ground.opacity = 0.4; });
// Navigate to underground viewpoint view.goTo({ position: { x: -122.4, y: 37.8, z: -500, // Negative z = underground spatialReference: { wkid: 4326 } }, tilt: 80 });
Local Scene Mode
Create Local Scene
<arcgis-scene basemap="topo-vector" viewing-mode="local"> <arcgis-zoom slot="top-left"></arcgis-zoom> </arcgis-scene>
Local Scene with Clipping Area
const viewElement = document.querySelector("arcgis-scene"); await viewElement.viewOnReady();
// Define clipping extent const clippingExtent = { xmax: -10834217, xmin: -10932882, ymax: 4493918, ymin: 4432667, spatialReference: { wkid: 3857 } };
// Set clipping area viewElement.clippingArea = clippingExtent; viewElement.extent = clippingExtent;
// Disable atmosphere for local scenes viewElement.environment = { atmosphereEnabled: false, starsEnabled: false };
Elevation Info
Elevation Modes
// Feature placement relative to ground/scene layer.elevationInfo = { mode: "on-the-ground" // Features draped on ground // mode: "relative-to-ground" // Features offset from ground // mode: "relative-to-scene" // Features offset from scene // mode: "absolute-height" // Features at absolute Z values };
Elevation with Offset
layer.elevationInfo = { mode: "relative-to-ground", offset: 100, // Meters above ground unit: "meters" };
Elevation with Expression
layer.elevationInfo = { mode: "relative-to-ground", featureExpressionInfo: { expression: "Geometry($feature).z * 10" // Exaggerate Z values }, unit: "meters" };
Dynamic Elevation Configuration
function updateElevationInfo(mode, offset, expression, unit) { layer.elevationInfo = { mode: mode, offset: Number(offset), featureExpressionInfo: { expression: expression || "0" }, unit: unit }; }
Screenshot Capture
Take Screenshot
const viewElement = document.querySelector("arcgis-scene");
// Take full view screenshot const screenshot = await viewElement.takeScreenshot({ format: "png" });
// Display screenshot const img = document.createElement("img"); img.src = screenshot.dataUrl; document.body.appendChild(img);
Screenshot of Specific Area
const screenshot = await viewElement.takeScreenshot({ area: { x: 100, y: 100, width: 500, height: 400 }, format: "png" });
Screenshot with Drag Selection
viewElement.addEventListener("arcgisViewDrag", (event) => { event.detail.stopPropagation(); // Prevent navigation
if (event.detail.action === "end") { const area = { x: Math.min(event.detail.origin.x, event.detail.x), y: Math.min(event.detail.origin.y, event.detail.y), width: Math.abs(event.detail.x - event.detail.origin.x), height: Math.abs(event.detail.y - event.detail.origin.y) };
viewElement.takeScreenshot({ area, format: "png" })
.then(screenshot => {
// Use screenshot.dataUrl or screenshot.data
});
} });
Download Screenshot
function downloadImage(filename, dataUrl) { const element = document.createElement("a"); element.href = dataUrl; element.download = filename; element.click(); }
const screenshot = await view.takeScreenshot({ format: "png" }); downloadImage("scene-screenshot.png", screenshot.dataUrl);
Atmosphere and Stars
Configure Atmosphere
view.environment = { atmosphereEnabled: true, // Show atmosphere haze starsEnabled: true, // Show stars at night lighting: { date: new Date() // Current sun position } };
Disable for Clean Visualization
view.environment = { atmosphereEnabled: false, starsEnabled: false };
View Constraints
Altitude Constraints
const view = new SceneView({ container: "viewDiv", map: scene, constraints: { altitude: { min: 20000000, // Minimum camera altitude max: 25000000 // Maximum camera altitude } } });
Focus Area
Create Focus Area
import FocusArea from "@arcgis/core/effects/FocusArea.js"; import Polygon from "@arcgis/core/geometry/Polygon.js"; import Collection from "@arcgis/core/core/Collection.js";
// Define focus area geometry const focusGeometry = new Polygon({ spatialReference: { wkid: 102100 }, rings: [[ [1288603, 6130075], [1288506, 6129722], [1288260, 6129821], [1288603, 6130075] ]] });
// Create focus area effect const focusArea = new FocusArea({ title: "Area of Interest", id: "focus-1", outline: { color: [255, 128, 128, 0.55] }, geometries: new Collection([focusGeometry]) });
// Add to view viewElement.focusAreas.areas.add(focusArea); viewElement.focusAreas.style = "bright"; // or "dark"
Focus Area Styles
// Bright style - highlights focus area viewElement.focusAreas.style = "bright";
// Dark style - darkens surrounding area viewElement.focusAreas.style = "dark";
Toggle Focus Area
// Disable focus area focusArea.enabled = false;
// Enable focus area focusArea.enabled = true;
Update Focus Area Geometry
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js";
const sketchVM = new SketchViewModel({ view: view, layer: graphicsLayer });
sketchVM.on("update", (event) => { // Update focus area with new geometry focusArea.geometries = new Collection([event.graphics[0].geometry]); });
Complete Example
<!DOCTYPE html> <html> <head> <script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script> <script src="https://js.arcgis.com/4.34/"></script> <script type="module" src="https://js.arcgis.com/4.34/map-components/"></script> <style> html, body { height: 100%; margin: 0; } </style> </head> <body> <arcgis-scene item-id="YOUR_WEBSCENE_ID"> <arcgis-zoom slot="top-left"></arcgis-zoom> </arcgis-scene>
<script type="module"> const viewElement = document.querySelector("arcgis-scene"); await viewElement.viewOnReady();
// Configure environment
viewElement.environment = {
lighting: {
directShadowsEnabled: true,
date: new Date()
},
atmosphereEnabled: true,
starsEnabled: true
};
// Enable underground navigation
viewElement.map.ground.navigationConstraint = { type: "none" };
viewElement.map.ground.opacity = 0.6;
// Configure layer elevation
const layer = viewElement.map.layers.getItemAt(0);
layer.elevationInfo = {
mode: "relative-to-ground",
offset: 50,
unit: "meters"
};
</script> </body> </html>
TypeScript Usage
Scene environment configurations use autocasting. For TypeScript safety, use as const :
// Use 'as const' for environment settings view.environment = { lighting: { date: new Date("2024-06-21T12:00:00"), directShadowsEnabled: true }, weather: { type: "sunny", cloudCover: 0.3 } as const, background: { type: "color", color: [0, 0, 0, 1] } as const };
Tip: See arcgis-core-maps skill for detailed guidance on autocasting vs explicit classes.
Common Pitfalls
Alpha compositing: Must set alphaCompositingEnabled: true for transparent backgrounds
Local scenes: Require clipping area and typically disable atmosphere/stars
Underground navigation: Must set ground.navigationConstraint.type = "none"
Shadow performance: directShadowsEnabled can impact performance
Elevation modes: "on-the-ground" ignores offset and expression settings
Screenshot CORS: External layers may block screenshot capture