# Arcgis Feature Effects

> 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.

- **Type:** Skill
- **Install:** `agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-feature-effects`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SaschaBrunnerCH](https://agentstack.voostack.com/s/saschabrunnerch)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context/tree/master/skills/arcgis-feature-effects

## Install

```sh
agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-feature-effects
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 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

```javascript
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

```javascript
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"` with `const 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

```javascript
layer.featureEffect = {
  filter: {
    where: "population > 100000",
  },
  includedEffect: "bloom(1.5, 0.5px, 0.2)",
  excludedEffect: "grayscale(100%) opacity(30%)",
};
```

### Feature Effect on LayerView

```javascript
const layerView = await view.whenLayerView(layer);

layerView.featureEffect = {
  filter: {
    where: "status = 'Active'",
  },
  excludedEffect: "grayscale(100%) opacity(50%)",
};
```

### Scale-Dependent Effects

```javascript
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

```javascript
layer.featureEffect = {
  filter: { where: "type = 'primary'" },
  excludedEffect: "opacity(25%)",
};
```

### Grayscale

```javascript
layer.featureEffect = {
  filter: { where: "category = 'important'" },
  excludedEffect: "grayscale(100%)",
};
```

### Blur

```javascript
layer.featureEffect = {
  filter: { where: "highlighted = 1" },
  excludedEffect: "blur(5px)",
};
```

### Drop Shadow

```javascript
layer.featureEffect = {
  filter: { where: "selected = 1" },
  includedEffect: "drop-shadow(3px, 3px, 4px, #000000)",
};
```

### Bloom (Glow)

```javascript
layer.featureEffect = {
  filter: { where: "active = 1" },
  includedEffect: "bloom(1.5, 0.5px, 0.2)",
};
```

### Brightness and Contrast

```javascript
layer.featureEffect = {
  filter: { where: "status = 'highlight'" },
  includedEffect: "brightness(150%) contrast(120%)",
  excludedEffect: "brightness(50%)",
};
```

### Combining Multiple Effects

```javascript
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

```javascript
layer.featureEffect = {
  filter: {
    where: "population > 50000 AND state = 'CA'",
  },
  excludedEffect: "grayscale(100%) opacity(30%)",
};
```

### Geometry-Based Filter

```javascript
const layerView = await view.whenLayerView(layer);

layerView.featureEffect = {
  filter: {
    geometry: polygon,
    spatialRelationship: "intersects",
  },
  excludedEffect: "grayscale(100%) opacity(30%)",
};
```

### Distance-Based Filter

```javascript
layerView.featureEffect = {
  filter: {
    geometry: point,
    spatialRelationship: "intersects",
    distance: 1000,
    units: "meters",
  },
  excludedEffect: "opacity(20%)",
};
```

### ObjectID Filter

```javascript
layerView.featureEffect = {
  filter: {
    objectIds: [1, 5, 10, 42],
  },
  includedEffect: "drop-shadow(3px, 3px, 4px)",
  excludedEffect: "grayscale(100%) opacity(40%)",
};
```

### Time-Based Filter

```javascript
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

```javascript
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

```javascript
// Add focus area to the view
view.focusAreas.areas.add(focusArea);

// Set visual style: "bright" or "dark"
view.focusAreas.style = "bright";
```

### Toggling Focus Areas

```javascript
// 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 geometries defining the focus         |
| `outline`    | `FocusAreaOutline`    | Outline style: `{ color }`                    |

## Layer Effects (Non-Feature)

Apply CSS-like effects to an entire layer (not per-feature).

```javascript
// 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.

```javascript
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

```javascript
// 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

```javascript
layer.displayFilterInfo = {
  where: "population > 10000",
};
```

### Scale-Dependent Display Filter

```javascript
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

```javascript
const layerView = await view.whenLayerView(layer);
const activeFilter = layerView.effectiveDisplayFilter?.title;
```

### Combining Display Filter with Feature Effect

```javascript
// 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

```javascript
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

```javascript
slider.on("thumb-drag", (event) => {
  const value = event.value;
  layer.featureEffect = {
    filter: { where: `value > ${value}` },
    excludedEffect: `opacity(${100 - value}%)`,
  };
});
```

### Clear Feature Effect

```javascript
layer.featureEffect = null;
// or
layerView.featureEffect = null;
```

## Effect with Histogram

```javascript
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 relationships
- `featureeffect-drop-shadow` - Scale-dependent drop shadow effects
- `featureeffect-layers-histogram` - Feature effects with histogram widget
- `featureeffect-multiple-effects` - Combining multiple visual effects
- `effect-blur-shadow` - Blur and shadow effects on layers
- `intro-effect-layer` - Introduction to layer effects
- `display-filter` - Scale-dependent display filtering
- `focus-area` - Focus areas in 3D SceneView
- `highlight-features-by-geometry` - Highlight features using geometry
- `blendmode-darkening` - Blend mode darkening effects
- `blendmode-grouplayer` - Blend modes on group layers
- `blendmode-multiple-layers` - Blend modes across multiple layers

## Common Pitfalls

1. **Layer vs LayerView**: Feature effects on `layer` affect all views; on `layerView` only that specific view.

   ```javascript
   // Affects all views
   layer.featureEffect = { ... };

   // Affects only this view
   const layerView = await view.whenLayerView(layer);
   layerView.featureEffect = { ... };
   ```

2. **Performance**: Complex effects (blur, bloom) on many features impact rendering performance. Use display filters to reduce the feature count first.

3. **Effect order**: When combining effects, they are applied in the order listed in the string.

4. **Display filter vs feature effect**: Use `displayFilterInfo` to hide features entirely (better performance). Use `featureEffect` to style included/excluded sets differently.

5. **Time extent filter**: Time-based filters require the layer to have time info configured. Without it, the filter is silently ignored.

6. **Spatial filter on LayerView only**: Geometry-based filters (`geometry`, `distance`) only work on `layerView.featureEffect`, not `layer.featureEffect`.

7. **Bloom parameters**: `bloom(strength, radius, threshold)` - threshold (0-1) controls which brightness level starts glowing. Higher values = less glow.

8. **Effect string syntax**: Effects are space-separated, not comma-separated. Incorrect syntax fails silently.

   ```javascript
   // Anti-pattern: comma-separated effects
   excludedEffect: "grayscale(100%), opacity(30%)";

   // Correct: space-separated effects
   excludedEffect: "grayscale(100%) opacity(30%)";
   ```

9. **Focus areas require Polygon geometry**: Only `Polygon` geometry is supported for `FocusArea.geometries`. Points and polylines are not supported.

10. **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 symbols
- `arcgis-smart-mapping` - Auto-generated renderers with histogram
- `arcgis-interaction` - User interaction and hit testing
- `arcgis-layers` - Layer types and configuration
- `arcgis-core-maps` - Map and view setup

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** [SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context](https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-feature-effects
- Seller: https://agentstack.voostack.com/s/saschabrunnerch
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
