如何在 Flutter 中创建文本剪切?
How to create a Text cutout in Flutter?
我正在尝试创建一个文本框,其中文本颜色应该是透明的,如果我更改背景容器的颜色..文本颜色也应该改变。例如,考虑这张图片
在这里,我有一个堆栈,第一个元素是一个带有 colour= black
的容器,因此我希望 MY TEXT 也为黑色。
我不想每次更改第一个容器的颜色时都手动设置文本的字体颜色。因为我可能计划稍后用动画填充容器并且我想要相同的动画 运行 上文也。
我尝试将文本 foreground 颜色设置为透明,将背景颜色设置为 orange 但这没有帮助,文本也变成了橙色因此是隐形的。
您需要使用 CustomPainter
和 TextPainter
以及混合模式。
在您的小部件树中:
return Container(
color: Colors.black,
height: 40.0,
child: Center(
child: CustomPaint(
painter: MyTextPainter(text: 'Hello'),
),
),
);
您的自定义文字画家:
class MyTextPainter extends CustomPainter {
MyTextPainter({this.text});
final String text;
@override
void paint(Canvas canvas, Size size) {
TextPainter textPainter = TextPainter(
text: TextSpan(
text: text,
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
),
),
textDirection: TextDirection.ltr,
);
textPainter.layout();
// Draw text
final textOffset = size.center(Offset.zero) - textPainter.size.center(Offset.zero);
final textRect = textOffset & textPainter.size;
// Your text box (orange in your example)
final boxRect = RRect.fromRectAndCorners(textRect.inflate(5.0));
final boxPaint = Paint()
..color = Colors.orange
..blendMode = BlendMode.srcOut;
canvas.saveLayer(boxRect.outerRect, Paint());
textPainter.paint(canvas, textOffset);
canvas.drawRRect(boxRect, boxPaint);
canvas.restore();
}
@override
bool shouldRepaint(MyTextPainter oldDelegate) => true;
}
在寻找更多选择时,我发现这个非常简单的方法可以实现我想要的。
ShaderMask(
blendMode: BlendMode.srcOut,
child: Text(
text,
),
shaderCallback: (bounds) =>
LinearGradient(colors: [Colors.black], stops: [0.0])
.createShader(bounds),
)
我正在尝试创建一个文本框,其中文本颜色应该是透明的,如果我更改背景容器的颜色..文本颜色也应该改变。例如,考虑这张图片
在这里,我有一个堆栈,第一个元素是一个带有 colour= black
的容器,因此我希望 MY TEXT 也为黑色。
我不想每次更改第一个容器的颜色时都手动设置文本的字体颜色。因为我可能计划稍后用动画填充容器并且我想要相同的动画 运行 上文也。
我尝试将文本 foreground 颜色设置为透明,将背景颜色设置为 orange 但这没有帮助,文本也变成了橙色因此是隐形的。
您需要使用 CustomPainter
和 TextPainter
以及混合模式。
在您的小部件树中:
return Container(
color: Colors.black,
height: 40.0,
child: Center(
child: CustomPaint(
painter: MyTextPainter(text: 'Hello'),
),
),
);
您的自定义文字画家:
class MyTextPainter extends CustomPainter {
MyTextPainter({this.text});
final String text;
@override
void paint(Canvas canvas, Size size) {
TextPainter textPainter = TextPainter(
text: TextSpan(
text: text,
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
),
),
textDirection: TextDirection.ltr,
);
textPainter.layout();
// Draw text
final textOffset = size.center(Offset.zero) - textPainter.size.center(Offset.zero);
final textRect = textOffset & textPainter.size;
// Your text box (orange in your example)
final boxRect = RRect.fromRectAndCorners(textRect.inflate(5.0));
final boxPaint = Paint()
..color = Colors.orange
..blendMode = BlendMode.srcOut;
canvas.saveLayer(boxRect.outerRect, Paint());
textPainter.paint(canvas, textOffset);
canvas.drawRRect(boxRect, boxPaint);
canvas.restore();
}
@override
bool shouldRepaint(MyTextPainter oldDelegate) => true;
}
在寻找更多选择时,我发现这个非常简单的方法可以实现我想要的。
ShaderMask(
blendMode: BlendMode.srcOut,
child: Text(
text,
),
shaderCallback: (bounds) =>
LinearGradient(colors: [Colors.black], stops: [0.0])
.createShader(bounds),
)