ArcGIS Feature Effects
Use this skill for applying visual effects, feature filters, display filters, focus areas, and blend modes to layers.
Import Patterns
Direct ESM Imports
import FeatureEffect from "@arcgis/core/layers/support/FeatureEffect.js";
import FeatureFilter from "@arcgis/core/layers/support/FeatureFilter.js";
import FocusArea from "@arcgis/core/effects/FocusArea.js";
import FocusAreas from "@arcgis/core/effects/FocusAreas.js";
import FocusAreaOutline from "@arcgis/core/effects/FocusAreaOutline.js";
CDN Dynamic Imports
const [FeatureEffect, FeatureFilter, FocusArea] = await $arcgis.import([
"@arcgis/core/layers/support/FeatureEffect.js",
"@arcgis/core/layers/support/FeatureFilter.js",
"@arcgis/core/effects/FocusArea.js"
]);
Note: Examples below use autocasting. For CDN usage, replace
import X from "path"withconst X = await $arcgis.import("path").
Feature Effect Basics
Feature effects divide features into two sets (included/excluded) based on a filter, then apply CSS-like effects to each set.
Basic Feature Effect
layer.featureEffect = {
filter: {
where: "population > 100000"
},
includedEffect: "bloom(1.5, 0.5px, 0.2)",
excludedEffect: "grayscale(100%) opacity(30%)"
};
Feature Effect on LayerView
const layerView = await view.whenLayerView(layer);
layerView.featureEffect = {
filter: {
where: "status = 'Active'"
},
excludedEffect: "grayscale(100%) opacity(50%)"
};
Scale-Dependent Effects
layerView.featureEffect = {
filter: {
where: "party_switch = 'R' OR party_switch = 'D'"
},
includedEffect: [
{ scale: 36978595, value: "drop-shadow(3px, 3px, 4px)" },
{ scale: 18489297, value: "drop-shadow(2px, 2px, 3px)" },
{ scale: 4622324, value: "drop-shadow(1px, 1px, 2px)" }
]
};
Effect Types Reference
| Effect | Syntax | Description |
|--------|--------|-------------|
| opacity | opacity(50%) | Transparency (0-100%) |
| grayscale | grayscale(100%) | Remove color (0-100%) |
| blur | blur(5px) | Gaussian blur |
| drop-shadow | drop-shadow(x, y, blur, color) | Shadow effect |
| bloom | bloom(strength, radius, threshold) | Glow effect |
| brightness | brightness(150%) | Adjust brightness |
| contrast | contrast(120%) | Adjust contrast |
| invert | invert(100%) | Invert colors |
| sepia | sepia(100%) | Sepia tone |
| saturate | saturate(200%) | Color saturation |
| hue-rotate | hue-rotate(180deg) | Rotate hue |
Individual Effect Examples
Opacity
layer.featureEffect = {
filter: { where: "type = 'primary'" },
excludedEffect: "opacity(25%)"
};
Grayscale
layer.featureEffect = {
filter: { where: "category = 'important'" },
excludedEffect: "grayscale(100%)"
};
Blur
layer.featureEffect = {
filter: { where: "highlighted = 1" },
excludedEffect: "blur(5px)"
};
Drop Shadow
layer.featureEffect = {
filter: { where: "selected = 1" },
includedEffect: "drop-shadow(3px, 3px, 4px, #000000)"
};
Bloom (Glow)
layer.featureEffect = {
filter: { where: "active = 1" },
includedEffect: "bloom(1.5, 0.5px, 0.2)"
};
Brightness and Contrast
layer.featureEffect = {
filter: { where: "status = 'highlight'" },
includedEffect: "brightness(150%) contrast(120%)",
excludedEffect: "brightness(50%)"
};
Combining Multiple Effects
layer.featureEffect = {
filter: { where: "status = 'active'" },
includedEffect: "drop-shadow(2px, 2px, 3px) brightness(120%)",
excludedEffect: "grayscale(100%) opacity(30%) blur(2px)"
};
Filter Types
Attribute Filter
layer.featureEffect = {
filter: {
where: "population > 50000 AND state = 'CA'"
},
excludedEffect: "grayscale(100%) opacity(30%)"
};
Geometry-Based Filter
const layerView = await view.whenLayerView(layer);
layerView.featureEffect = {
filter: {
geometry: polygon,
spatialRelationship: "intersects"
},
excludedEffect: "grayscale(100%) opacity(30%)"
};
Distance-Based Filter
layerView.featureEffect = {
filter: {
geometry: point,
spatialRelationship: "intersects",
distance: 1000,
units: "meters"
},
excludedEffect: "opacity(20%)"
};
ObjectID Filter
layerView.featureEffect = {
filter: {
objectIds: [1, 5, 10, 42]
},
includedEffect: "drop-shadow(3px, 3px, 4px)",
excludedEffect: "grayscale(100%) opacity(40%)"
};
Time-Based Filter
layer.featureEffect = {
filter: {
timeExtent: {
start: new Date("2020-01-01"),
end: new Date("2020-12-31")
}
},
excludedEffect: "opacity(20%)"
};
Spatial Relationships
| Relationship | Description |
|-------------|-------------|
| intersects | Features that intersect the geometry |
| contains | Features that contain the geometry |
| within | Features within the geometry |
| crosses | Features that cross the geometry |
| overlaps | Features that overlap the geometry |
| touches | Features that touch the geometry |
| disjoint | Features not intersecting the geometry |
| envelope-intersects | Envelope intersection (faster) |
Focus Areas (3D SceneView)
Focus areas highlight specific polygon regions in a 3D SceneView, dimming everything outside. Useful for drawing attention to areas of interest in 3D scenes.
Creating a Focus Area
import FocusArea from "@arcgis/core/effects/FocusArea.js";
import Collection from "@arcgis/core/core/Collection.js";
const focusArea = new FocusArea({
title: "Area of Interest",
id: "focus-1",
enabled: true,
outline: { color: [255, 128, 128, 0.55] },
geometries: new Collection([polygon])
});
Adding to a SceneView
// Add focus area to the view
view.focusAreas.areas.add(focusArea);
// Set visual style: "bright" or "dark"
view.focusAreas.style = "bright";
Toggling Focus Areas
// Disable without removing
focusArea.enabled = false;
// Re-enable with different style
focusArea.enabled = true;
view.focusAreas.style = "dark";
// Remove entirely
view.focusAreas.areas.remove(focusArea);
FocusArea Properties
| Property | Type | Description |
|----------|------|-------------|
| title | string | Title of the focus area |
| id | string | Unique identifier (auto-generated if omitted) |
| enabled | boolean | Whether displayed (default: true) |
| geometries | Collection<Polygon> | Polygon geometries defining the focus |
| outline | FocusAreaOutline | Outline style: { color } |
Layer Effects (Non-Feature)
Apply CSS-like effects to an entire layer (not per-feature).
// Apply effect to the whole layer
layer.effect = "bloom(1.5, 0.5px, 0.2)";
// Multiple effects
layer.effect = "drop-shadow(3px, 3px, 4px) brightness(120%)";
// Remove effect
layer.effect = null;
Blend Modes
Blend modes control how a layer blends with layers beneath it.
layer.blendMode = "multiply"; // Default is "normal"
Blend Mode Categories
| Category | Modes |
|----------|-------|
| Darkening | multiply, darken, color-burn |
| Lightening | screen, lighten, color-dodge |
| Contrast | overlay, soft-light, hard-light |
| Component | hue, saturation, luminosity, color |
| Composite | destination-in, destination-out, destination-over, source-in |
| Inversion | difference, exclusion, minus |
| Other | normal, average, vivid-light, reflect |
Common Blend Mode Patterns
// Darken: show dark features on light basemap
layer.blendMode = "multiply";
// Lighten: show light features on dark basemap
layer.blendMode = "screen";
// Masking: clip layers using another layer shape
maskLayer.blendMode = "destination-in";
Display Filters
Display filters completely hide features (better performance than effects since features are not rendered).
Simple Display Filter
layer.displayFilterInfo = {
where: "population > 10000"
};
Scale-Dependent Display Filter
const layer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0",
displayFilterInfo: {
mode: "scale",
filters: [
{
title: "Major rivers",
minScale: 0,
maxScale: 36_978_595,
where: "streamOrder >= 8"
},
{
title: "Large rivers",
minScale: 36_978_595,
maxScale: 18_489_297,
where: "streamOrder >= 7"
},
{
title: "All rivers",
minScale: 4_622_324,
maxScale: 0
}
]
}
});
Checking Active Display Filter
const layerView = await view.whenLayerView(layer);
const activeFilter = layerView.effectiveDisplayFilter?.title;
Combining Display Filter with Feature Effect
// Display filter hides deleted features entirely (performance)
layer.displayFilterInfo = {
where: "status != 'deleted'"
};
// Feature effect styles remaining features
layer.featureEffect = {
filter: { where: "status = 'active'" },
excludedEffect: "opacity(50%)"
};
Interactive Feature Effects
Effect on Click
view.on("click", async (event) => {
const response = await view.hitTest(event);
const graphic = response.results[0]?.graphic;
if (graphic) {
const oid = graphic.attributes.OBJECTID;
layerView.featureEffect = {
filter: {
objectIds: [oid]
},
includedEffect: "drop-shadow(3px, 3px, 4px)",
excludedEffect: "grayscale(100%) opacity(40%)"
};
}
});
Effect with Slider
slider.on("thumb-drag", (event) => {
const value = event.value;
layer.featureEffect = {
filter: { where: `value > ${value}` },
excludedEffect: `opacity(${100 - value}%)`
};
});
Clear Feature Effect
layer.featureEffect = null;
// or
layerView.featureEffect = null;
Effect with Histogram
import histogram from "@arcgis/core/smartMapping/statistics/histogram.js";
const histogramResult = await histogram({
layer: layer,
field: "population",
numBins: 30
});
const slider = new HistogramRangeSlider({
bins: histogramResult.bins,
min: histogramResult.minValue,
max: histogramResult.maxValue,
values: [histogramResult.minValue, histogramResult.maxValue]
});
slider.on("thumb-drag", () => {
const [min, max] = slider.values;
layerView.featureEffect = {
filter: {
where: `population >= ${min} AND population <= ${max}`
},
excludedEffect: "grayscale(100%) opacity(30%)"
};
});
Reference Samples
featureeffect-geometry- Geometry-based feature effects with spatial relationshipsfeatureeffect-drop-shadow- Scale-dependent drop shadow effectsfeatureeffect-layers-histogram- Feature effects with histogram widgetfeatureeffect-multiple-effects- Combining multiple visual effectseffect-blur-shadow- Blur and shadow effects on layersintro-effect-layer- Introduction to layer effectsdisplay-filter- Scale-dependent display filteringfocus-area- Focus areas in 3D SceneViewhighlight-features-by-geometry- Highlight features using geometryblendmode-darkening- Blend mode darkening effectsblendmode-grouplayer- Blend modes on group layersblendmode-multiple-layers- Blend modes across multiple layers
Common Pitfalls
-
Layer vs LayerView: Feature effects on
layeraffect all views; onlayerViewonly that specific view.// Affects all views layer.featureEffect = { ... }; // Affects only this view const layerView = await view.whenLayerView(layer); layerView.featureEffect = { ... }; -
Performance: Complex effects (blur, bloom) on many features impact rendering performance. Use display filters to reduce the feature count first.
-
Effect order: When combining effects, they are applied in the order listed in the string.
-
Display filter vs feature effect: Use
displayFilterInfoto hide features entirely (better performance). UsefeatureEffectto style included/excluded sets differently. -
Time extent filter: Time-based filters require the layer to have time info configured. Without it, the filter is silently ignored.
-
Spatial filter on LayerView only: Geometry-based filters (
geometry,distance) only work onlayerView.featureEffect, notlayer.featureEffect. -
Bloom parameters:
bloom(strength, radius, threshold)- threshold (0-1) controls which brightness level starts glowing. Higher values = less glow. -
Effect string syntax: Effects are space-separated, not comma-separated. Incorrect syntax fails silently.
// Anti-pattern: comma-separated effects excludedEffect: "grayscale(100%), opacity(30%)" // Correct: space-separated effects excludedEffect: "grayscale(100%) opacity(30%)" -
Focus areas require Polygon geometry: Only
Polygongeometry is supported forFocusArea.geometries. Points and polylines are not supported. -
Scale-dependent effects: When using the array format for scale-dependent effects, provide at least two stops for smooth interpolation between scales.
Related Skills
arcgis-visualization- Renderers and symbolsarcgis-smart-mapping- Auto-generated renderers with histogramarcgis-interaction- User interaction and hit testingarcgis-layers- Layer types and configurationarcgis-core-maps- Map and view setup