Documentation Index
Fetch the complete documentation index at: https://mintlify.com/shopify/react-native-skia/llms.txt
Use this file to discover all available pages before exploring further.
The ImageShader component allows you to use images as shaders, providing control over tiling, fitting, and transformations. This enables you to create patterns, textures, and complex visual effects.
Image Shader
The ImageShader returns an image as a shader with configurable tiling modes. It uses cubic sampling for high-quality rendering.
Props
| Name | Type | Description |
|---|
| image | SkImage | The image instance to use as a shader |
| tx | TileMode | Horizontal tiling mode: clamp, repeat, mirror, or decal (default: decal) |
| ty | TileMode | Vertical tiling mode: clamp, repeat, mirror, or decal (default: decal) |
| fit | Fit | How to fit the image in the destination rectangle (default: none) |
| rect | SkRect | Destination rectangle for fit calculation |
| transform | Transform2d | Additional transformations to apply (see transformations) |
| sampling | Sampling | Sampling method for the image (see sampling options) |
Basic Example
import { Canvas, Circle, ImageShader, useImage } from "@shopify/react-native-skia";
const ImageShaderDemo = () => {
const image = useImage(require("./assets/oslo.jpg"));
if (!image) {
return null;
}
return (
<Canvas style={{ flex: 1 }}>
<Circle cx={128} cy={128} r={128}>
<ImageShader
image={image}
fit="cover"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
</Circle>
</Canvas>
);
};
Tiling Modes
Control how the image repeats using tile modes:
Clamp
Extends edge pixels:
<ImageShader image={image} tx="clamp" ty="clamp" />
Repeat
Repeats the image:
import { Canvas, Rect, ImageShader, useImage } from "@shopify/react-native-skia";
const RepeatPattern = () => {
const image = useImage(require("./assets/pattern.png"));
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256}>
<ImageShader image={image} tx="repeat" ty="repeat" />
</Rect>
</Canvas>
);
};
Mirror
Mirrors the image:
<ImageShader image={image} tx="mirror" ty="mirror" />
Decal
Draws the image once, transparent elsewhere:
<ImageShader image={image} tx="decal" ty="decal" />
Fitting Images
The fit property works with the rect property to control how the image fits within a rectangle:
Contain
Fits the entire image within the bounds:
<ImageShader
image={image}
fit="contain"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
Cover
Covers the entire rectangle, may crop the image:
<ImageShader
image={image}
fit="cover"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
Fill
Stretches the image to fill the rectangle:
<ImageShader
image={image}
fit="fill"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
Other Fit Options
fitWidth: Scales to match width
fitHeight: Scales to match height
scaleDown: Like contain, but never scales up
none: No fitting applied (default)
Apply transformations to image shaders:
import { Canvas, Rect, ImageShader, useImage } from "@shopify/react-native-skia";
const TransformedImage = () => {
const image = useImage(require("./assets/texture.jpg"));
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256}>
<ImageShader
image={image}
tx="repeat"
ty="repeat"
transform={[
{ scale: 0.5 },
{ rotate: Math.PI / 4 }
]}
/>
</Rect>
</Canvas>
);
};
Sampling Options
Control image quality with sampling options:
Cubic Sampling (Best Quality)
import { Canvas, Rect, ImageShader, useImage, CubicSampling } from "@shopify/react-native-skia";
const HighQuality = () => {
const image = useImage(require("./assets/photo.jpg"));
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256}>
<ImageShader
image={image}
fit="cover"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
sampling={CubicSampling}
/>
</Rect>
</Canvas>
);
};
Filter Modes
import { FilterMode, MipmapMode } from "@shopify/react-native-skia";
<ImageShader
image={image}
sampling={{
filter: FilterMode.Linear,
mipmap: MipmapMode.Linear
}}
/>
Creating Patterns
Tiled Pattern
import { Canvas, Fill, ImageShader, useImage } from "@shopify/react-native-skia";
const TiledPattern = () => {
const pattern = useImage(require("./assets/tile.png"));
return (
<Canvas style={{ flex: 1 }}>
<Fill>
<ImageShader
image={pattern}
tx="repeat"
ty="repeat"
/>
</Fill>
</Canvas>
);
};
Kaleidoscope Effect
import { Canvas, Rect, ImageShader, useImage } from "@shopify/react-native-skia";
const Kaleidoscope = () => {
const image = useImage(require("./assets/photo.jpg"));
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256}>
<ImageShader
image={image}
tx="mirror"
ty="mirror"
fit="cover"
rect={{ x: 0, y: 0, width: 128, height: 128 }}
/>
</Rect>
</Canvas>
);
};
Combining with Other Shaders
Blend image shaders with other effects:
import {
Canvas,
Rect,
Blend,
ImageShader,
LinearGradient,
useImage,
vec
} from "@shopify/react-native-skia";
const BlendedImage = () => {
const image = useImage(require("./assets/photo.jpg"));
return (
<Canvas style={{ flex: 1 }}>
<Rect x={0} y={0} width={256} height={256}>
<Blend mode="multiply">
<ImageShader
image={image}
fit="cover"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
<LinearGradient
start={vec(0, 0)}
end={vec(0, 256)}
colors={["rgba(255,255,255,0)", "rgba(0,0,0,0.8)"]}
/>
</Blend>
</Rect>
</Canvas>
);
};
Using with Runtime Shaders
Image shaders can be passed to custom runtime shaders:
import {
Canvas,
Fill,
Shader,
ImageShader,
Skia,
useImage
} from "@shopify/react-native-skia";
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
half4 main(float2 xy) {
xy.x += sin(xy.y / 3) * 4;
return image.eval(xy);
}
`)!;
const WavyImage = () => {
const image = useImage(require("./assets/oslo.jpg"));
if (!image) return null;
return (
<Canvas style={{ width: 256, height: 256 }}>
<Fill>
<Shader source={source}>
<ImageShader
image={image}
fit="cover"
rect={{ x: 0, y: 0, width: 256, height: 256 }}
/>
</Shader>
</Fill>
</Canvas>
);
};
- Reuse
SkImage instances when possible
- Use appropriate sampling modes for your use case
- Consider using lower resolution images for patterns
- Cache images loaded with
useImage
- Use
decal tile mode when you don’t need tiling
Loading Images
Images are loaded using the useImage hook:
import { useImage } from "@shopify/react-native-skia";
// From bundle
const image1 = useImage(require("./assets/photo.jpg"));
// From network
const image2 = useImage("https://example.com/image.jpg");
// From native bundle (iOS/Android)
const image3 = useImage("Logo");
See the Images Overview for more details on loading images.
See Also