Image filters modify the appearance of rendered content. They can be applied to individual shapes or groups of elements.
Blur
Applies a Gaussian blur effect.
import { Canvas, Circle, Blur } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={100} color="blue">
<Blur blur={10} />
</Circle>
</Canvas>
Props
blur
number | { x: number, y: number }
required
Blur radius in pixels. Can be a single number for both directions or an object with x and y values for directional blur.
mode
TileMode
default:"'decal'"
How the filter extends beyond bounds:
clamp: Extends edge pixels
repeat: Repeats the image
mirror: Mirrors the image
decal: Transparent outside (default)
Offset
Shifts the image by a specified distance.
import { Canvas, Circle, Offset } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={50} color="red">
<Offset x={20} y={20} />
</Circle>
</Canvas>
Props
Horizontal offset in pixels
Vertical offset in pixels
Shadow
Creates drop shadow or inner shadow effects.
import { Canvas, RoundedRect, Shadow } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<RoundedRect x={50} y={50} width={200} height={200} r={20} color="white">
<Shadow dx={5} dy={5} blur={10} color="rgba(0,0,0,0.5)" />
</RoundedRect>
</Canvas>
Props
If true, creates an inner shadow instead of drop shadow
If true, only renders the shadow without the source content
Morphology
Erodes or dilates the image.
import { Canvas, Circle, Morphology } from "@shopify/react-native-skia";
// Dilate (expand)
<Circle cx={150} cy={150} r={50} color="blue">
<Morphology operator="dilate" radius={5} />
</Circle>
// Erode (shrink)
<Circle cx={150} cy={150} r={50} color="red">
<Morphology operator="erode" radius={3} />
</Circle>
Props
operator
'erode' | 'dilate'
required
erode: Shrinks bright areas
dilate: Expands bright areas
radius
number | { x: number, y: number }
required
Morphology radius. Can be uniform or directional.
Displacement Map
Distorts an image based on color channels from another image.
import { Canvas, Image, DisplacementMap, useImage } from "@shopify/react-native-skia";
export default function DisplacementExample() {
const source = useImage(require("./source.png"));
const displacement = useImage(require("./displacement.png"));
if (!source || !displacement) return null;
return (
<Canvas style={{ flex: 1 }}>
<Image image={source} x={0} y={0} width={300} height={300}>
<DisplacementMap
channelX="r"
channelY="g"
scale={20}
>
<Image image={displacement} x={0} y={0} width={300} height={300} />
</DisplacementMap>
</Image>
</Canvas>
);
}
Props
Color channel for X displacement: 'r', 'g', 'b', or 'a'
Color channel for Y displacement: 'r', 'g', 'b', or 'a'
Displacement scale factor
The displacement map source (usually an Image)
Runtime Shader
Apply custom shader effects as image filters.
import { Canvas, Circle, RuntimeShader, Skia } from "@shopify/react-native-skia";
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
uniform float intensity;
half4 main(vec2 coord) {
half4 color = image.eval(coord);
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
return mix(color, vec4(gray, gray, gray, color.a), intensity);
}
`);
export default function GrayscaleFilter() {
return (
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={100} color="rainbow">
<RuntimeShader source={source} uniforms={{ intensity: 0.8 }} />
</Circle>
</Canvas>
);
}
Props
Compiled runtime shader effect
Uniform values to pass to the shader
Combining Filters
Chain multiple filters together:
import { Canvas, Rect, Blur, Shadow, Morphology } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Rect x={50} y={50} width={200} height={200} color="purple">
<Shadow dx={3} dy={3} blur={5} color="rgba(0,0,0,0.3)" />
<Blur blur={2} />
<Morphology operator="dilate" radius={1} />
</Rect>
</Canvas>
Backdrop Filter
Applies filters to content behind an element.
import { Canvas, Circle, Rect, BackdropFilter, Blur } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
{/* Background content */}
<Circle cx={150} cy={150} r={100} color="red" />
{/* Blurred overlay */}
<BackdropFilter filter={<Blur blur={10} />}>
<Rect x={100} y={100} width={100} height={100} color="rgba(255,255,255,0.3)" />
</BackdropFilter>
</Canvas>
BackdropBlur Component
Convenience component for backdrop blur:
import { Canvas, Circle, Rect, BackdropBlur } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={100} color="blue" />
<BackdropBlur blur={15}>
<Rect x={100} y={100} width={100} height={100} color="rgba(255,255,255,0.5)" />
</BackdropBlur>
</Canvas>
Examples
Card with Shadow
import { Canvas, RoundedRect, Shadow } from "@shopify/react-native-skia";
<Canvas style={{ width: 300, height: 200 }}>
<RoundedRect x={20} y={20} width={260} height={160} r={12} color="white">
<Shadow
dx={0}
dy={4}
blur={12}
color="rgba(0, 0, 0, 0.15)"
/>
</RoundedRect>
</Canvas>
Glow Effect
import { Canvas, Circle, Shadow } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={50} color="cyan">
<Shadow dx={0} dy={0} blur={20} color="cyan" shadowOnly />
</Circle>
<Circle cx={150} cy={150} r={50} color="cyan" />
</Canvas>
Frosted Glass
import { Canvas, Image, Rect, BackdropBlur, useImage } from "@shopify/react-native-skia";
export default function FrostedGlass() {
const image = useImage(require("./background.jpg"));
if (!image) return null;
return (
<Canvas style={{ flex: 1 }}>
<Image image={image} fit="cover" x={0} y={0} width={300} height={400} />
<BackdropBlur blur={20}>
<Rect
x={50}
y={150}
width={200}
height={100}
color="rgba(255, 255, 255, 0.3)"
/>
</BackdropBlur>
</Canvas>
);
}
Neon Text Effect
import { Canvas, Text, Shadow, matchFont } from "@shopify/react-native-skia";
const font = matchFont({ fontSize: 72, fontWeight: "bold" });
<Canvas style={{ flex: 1 }}>
<Text x={50} y={150} text="NEON" font={font} color="#00FFFF">
<Shadow dx={0} dy={0} blur={10} color="#00FFFF" shadowOnly />
<Shadow dx={0} dy={0} blur={20} color="#00FFFF" shadowOnly />
<Shadow dx={0} dy={0} blur={30} color="#00FFFF" shadowOnly />
</Text>
<Text x={50} y={150} text="NEON" font={font} color="white" />
</Canvas>
- Image filters create offscreen buffers and can be expensive
- Blur is one of the most expensive filters - use smaller radius values when possible
- Combining multiple filters compounds the performance cost
- Use backdrop filters sparingly as they process all content behind the element
- Consider using simpler effects for animations