This tutorial shows you the usage of ShaderMask
in Flutter.
Let's start with a case where we need to use ShaderMask
. For example, there is a png image of a creature and we want to apply a gradient to the creature, not the background. If we apply the gradient to decoration
property, as shown in the below example, what will we get is the gradient is applied to the background.
body: Center(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.orange, Colors.yellow],
)
),
child: Image.asset('assets/images/pikachu.png')
)
)
Output:
Actually Flutter provides a list of BlendMode enum as you can see on this page. For this case, the most suitable enum is srcATop
whose descrption is 'Composite the source image over the destination image, but only where it overlaps the destination'. The question is how to use the BlendMode
as the Gradient
classes don't have a property for it.
Flutter has a widget called ShaderMask
, which applies a mask from a Shader
to its child. It can be used to apply effects such as gradients or images.
To apply ShaderMask
to a widget, just wrap the widget as the child of the ShaderMask
widget. In using ShaderMask
, you need to provide a ShaderCallback
.It's a callback function that accepts a parameter of type Rect
and returns a Shader
. Inside, you create a Shader
that will be applied on the given Rect
.
A shader can be created from a Gradient
, including LinearGradient
and RadialGradient
. Those implementations of Gradient
have createShader
method that returns a Shader
.
body: Center(
child: ShaderMask(
blendMode: BlendMode.srcATop,
shaderCallback: (Rect bounds) {
return LinearGradient(
colors: [Colors.orange, Colors.yellow],
).createShader(bounds);
},
child: Image.asset('assets/images/pikachu.png')
),
),
Output:
Here's another example with different BlendMode
, this time it's applied to a Text
widget.
body: Center(
child: ShaderMask(
blendMode: BlendMode.srcIn,
shaderCallback: (Rect bounds) {
return LinearGradient(
colors: [Colors.red, Colors.blue],
tileMode: TileMode.mirror,
).createShader(bounds);
},
child: const Text('ShaderMaskTutorial', style: TextStyle(fontSize: 36)),
),
),
Output:
That's how to use ShaderMask
widget which is very useful for applying shader effects to a widget. Choosing the right BlendMode
is very important to get the desired result.