花里胡哨的文字特效,你学会了吗?
前言
我们的 App 大部分时候的文字都是一种颜色,实际上,文字的颜色也可以多姿多彩。我们今天就来介绍一个能够轻松实现文字渐变色的组件 —— ShaderMask
。ShaderMask
能够构建一个着色器(shader),然后覆盖(mask)到它的子组件上,从而改变子组件的颜色。
ShaderMask 实现渐变色文字
ShaderMask
的构造函数定义如下。
const ShaderMask({
Key? key,
required this.shaderCallback,
this.blendMode = BlendMode.modulate,
Widget? child,
})
其中关键的参数是 shaderCallback
回调方法,通过 回调方法可以构建一个着色器来为子组件着色,典型的做法是使用 Gradient
的子类(如 LinearGradient
和 RadialGradial
)来创建着色器。blendMode
参数则用于设置着色的方式。
因此,我们可以利用LinearGradient
来实现渐变色文字,示例代码如下,其中 blendMode
选择为 BlendMode.srcIn
是忽略子组件原有的颜色,使用着色器来对子组件着色。
ShaderMask(
shaderCallback: (rect) {
return LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.blue,
Colors.green[300]!,
Colors.orange[400]!,
Colors.red,
],
).createShader(rect);
},
blendMode: BlendMode.srcIn,
child: const Text(
'岛上码农',
style: TextStyle(
fontSize: 36.0,
fontWeight: FontWeight.bold,
),
),
),
实现效果如下图。
实际上,不仅仅能够对文字着色,还可以对图片着色,比如我们使用一个 Row
组件在文字前面增加一个Image
组件,可以实现下面的效果。
让渐变色动起来
静态的渐变色着色还不够,Gradient
还有个 transform
来实现三维空间变换的渐变效果,我们可以利用这个参数和动画组件实现动画效果,比如下面这样。
这里其实就是使用了动画控制 transform
实现横向平移。由于 transform
是一个 GradientTransform
类,实现这样的效果需要定义一个GradientTransform
子类,如下所示。
@immutable
class SweepTransform extends GradientTransform {
const SweepTransform(this.dx, this.dy);
final double dx;
final double dy;
@override
Matrix4 transform(Rect bounds, {TextDirection? textDirection}) {
return Matrix4.identity()..translate(dx, dy);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other.runtimeType != runtimeType) {
return false;
}
return other is SweepTransform && other.dx == dx && other.dy == dy;
}
@override
int get hashCode => dx.hashCode & dy.hashCode;
}
然后通过 Animation
动画对象的值控制渐变色平移的距离就可以实现渐变色横向扫过的效果了,代码如下所示。
ShaderMask(
shaderCallback: (rect) {
return LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.blue,
Colors.green[300]!,
Colors.orange[400]!,
Colors.red,
],
transform: SweepTransform(
(_animation.value - 0.5) * rect.width, 0.0),
).createShader(rect);
},
blendMode: BlendMode.srcIn,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/logo.png',
scale: 2,
),
const Text(
'岛上码农',
style: TextStyle(
fontSize: 36.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
图片填充
除了使用渐变色之外,我们还可以利用 ImageShader 使用图片填充文字,实现一些其他的文字特效,比如用火焰图片作为背景,让文字看起来像燃烧了一样。
实现的代码如下,其中动效是通过 ImageShader
的构造函数的第4个参数的矩阵matrix4运算实现的,相当于是让填充图片移动来实现火焰往上升的效果。
ShaderMask(
shaderCallback: (rect) {
return ImageShader(
fillImage,
TileMode.decal,
TileMode.decal,
(Matrix4.identity()
..translate(-20.0 * _animation.value,
-150.0 * _animation.value))
.storage);
},
blendMode: BlendMode.srcIn,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/logo.png',
scale: 2,
),
const Text(
'岛上码农',
style: TextStyle(
fontSize: 36.0,
fontWeight: FontWeight.bold,
),
),
],
),
)
总结
本篇介绍了 ShaderMask
组件的应用,通过 ShaderMask
组件我们可以对子组件进行着色,从而改变子组件原来的颜色,实现如渐变色填充、图片填充等效果。本篇完整源码已提交至:实用组件相关源码。
链接:https://juejin.cn/post/7172513057044692999
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。