skills/arcgis-feature-effects/SKILL.md
Apply visual effects, filters, focus areas, and blend modes to map layers. Use for highlighting features, spatial filtering, display filters, and CSS-like visual emphasis.
npx skillsauth add SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context arcgis-feature-effectsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill for applying visual effects, feature filters, display filters, focus areas, and blend modes to layers.
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";
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 effects divide features into two sets (included/excluded) based on a filter, then apply CSS-like effects to each set.
layer.featureEffect = {
filter: {
where: "population > 100000",
},
includedEffect: "bloom(1.5, 0.5px, 0.2)",
excludedEffect: "grayscale(100%) opacity(30%)",
};
const layerView = await view.whenLayerView(layer);
layerView.featureEffect = {
filter: {
where: "status = 'Active'",
},
excludedEffect: "grayscale(100%) opacity(50%)",
};
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 | 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 |
layer.featureEffect = {
filter: { where: "type = 'primary'" },
excludedEffect: "opacity(25%)",
};
layer.featureEffect = {
filter: { where: "category = 'important'" },
excludedEffect: "grayscale(100%)",
};
layer.featureEffect = {
filter: { where: "highlighted = 1" },
excludedEffect: "blur(5px)",
};
layer.featureEffect = {
filter: { where: "selected = 1" },
includedEffect: "drop-shadow(3px, 3px, 4px, #000000)",
};
layer.featureEffect = {
filter: { where: "active = 1" },
includedEffect: "bloom(1.5, 0.5px, 0.2)",
};
layer.featureEffect = {
filter: { where: "status = 'highlight'" },
includedEffect: "brightness(150%) contrast(120%)",
excludedEffect: "brightness(50%)",
};
layer.featureEffect = {
filter: { where: "status = 'active'" },
includedEffect: "drop-shadow(2px, 2px, 3px) brightness(120%)",
excludedEffect: "grayscale(100%) opacity(30%) blur(2px)",
};
layer.featureEffect = {
filter: {
where: "population > 50000 AND state = 'CA'",
},
excludedEffect: "grayscale(100%) opacity(30%)",
};
const layerView = await view.whenLayerView(layer);
layerView.featureEffect = {
filter: {
geometry: polygon,
spatialRelationship: "intersects",
},
excludedEffect: "grayscale(100%) opacity(30%)",
};
layerView.featureEffect = {
filter: {
geometry: point,
spatialRelationship: "intersects",
distance: 1000,
units: "meters",
},
excludedEffect: "opacity(20%)",
};
layerView.featureEffect = {
filter: {
objectIds: [1, 5, 10, 42],
},
includedEffect: "drop-shadow(3px, 3px, 4px)",
excludedEffect: "grayscale(100%) opacity(40%)",
};
layer.featureEffect = {
filter: {
timeExtent: {
start: new Date("2020-01-01"),
end: new Date("2020-12-31"),
},
},
excludedEffect: "opacity(20%)",
};
| 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 highlight specific polygon regions in a 3D SceneView, dimming everything outside. Useful for drawing attention to areas of interest in 3D scenes.
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]),
});
// Add focus area to the view
view.focusAreas.areas.add(focusArea);
// Set visual style: "bright" or "dark"
view.focusAreas.style = "bright";
// 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);
| 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 } |
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 control how a layer blends with layers beneath it.
layer.blendMode = "multiply"; // Default is "normal"
| 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 |
// 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 completely hide features (better performance than effects since features are not rendered).
layer.displayFilterInfo = {
where: "population > 10000",
};
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,
},
],
},
});
const layerView = await view.whenLayerView(layer);
const activeFilter = layerView.effectiveDisplayFilter?.title;
// 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%)",
};
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%)",
};
}
});
slider.on("thumb-drag", (event) => {
const value = event.value;
layer.featureEffect = {
filter: { where: `value > ${value}` },
excludedEffect: `opacity(${100 - value}%)`,
};
});
layer.featureEffect = null;
// or
layerView.featureEffect = null;
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%)",
};
});
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 layersLayer vs LayerView: Feature effects on layer affect all views; on layerView only 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 displayFilterInfo to hide features entirely (better performance). Use featureEffect to 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 on layerView.featureEffect, not layer.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 Polygon geometry is supported for FocusArea.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.
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 setupdevelopment
Build map user interfaces with ArcGIS widgets, Map Components, and Calcite Design System. Use for adding legends, layer lists, search, tables, time sliders, and custom UI layouts.
development
Add specialized widgets including BuildingExplorer, FloorFilter, Track, Locate, HistogramRangeSlider, ScaleBar, Compass, NavigationToggle, and media viewers. Use for building exploration, indoor mapping, GPS tracking, and data histograms.
data-ai
Style and render geographic data with renderers, symbols, and visual variables. Use for creating thematic maps, heatmaps, class breaks, unique values, labels, and 3D visualization.
tools
Work with ArcGIS Utility Networks for modeling and analyzing connected infrastructure including network tracing, associations visualization, and topology validation. Use for electric, gas, water, and telecom network analysis.