颤动:自定义形状作为文本背景
flutter: custom shape as text background
我需要在 flutter 中实现这个:
我尝试制作 Row
并将背景设置为 Text
来处理矩形,然后 ClipPath
来制作三角形。这样做的问题是边缘不精确(您可以在下图中的矩形和三角形之间看到一条细线),而且 ClipPath
具有固定大小,所以如果我想更改文本大小有些时候我将不得不再次 fine-tune 三角形。
这是我的代码:
class TriangleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.lineTo(0.0, size.height);
path.lineTo(size.width / 3, size.height);
path.close();
return path;
}
@override
bool shouldReclip(TriangleClipper oldClipper) => false;
}
Row(
children: [
Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
"a label",
),
),
),
ClipPath(
clipper: TriangleClipper(),
child: Container(
color: Colors.orange,
height: 23,
width: 20,
),
)
],
)
我虽然在 ClipPath
的 child 中使用 double.infinity
而不是固定大小会解决它,但这样做会使三角形消失(可能它变得太大了我不能'看不到它或落后于某些东西)。
解决这个问题的正确方法是什么?我想我可以使用 ClipPath
绘制梯形,但如何制作梯形以使其宽度适应 Text
的长度?
您可以试试下面的代码:
import 'dart:ui' as ui;
child: CustomPaint(
size: Size(WIDTH,(WIDTH*0.625).toDouble()), //You can Replace [WIDTH] with your desired width for Custom Paint and height will be calculated automatically
painter: RPSCustomPainter(),
),
class RPSCustomPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Paint paint_0 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 1;
paint_0.shader = ui.Gradient.linear(Offset(size.width*0.29,size.height*0.28),Offset(size.width*0.29,size.height*0.28),[Color(0xff7c1010),Color(0xffffffff)],[0.00,1.00]);
Path path_0 = Path();
path_0.moveTo(size.width*0.2937500,size.height*0.2780000);
canvas.drawPath(path_0, paint_0);
Paint paint_1 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 1;
Path path_1 = Path();
path_1.moveTo(size.width*0.3750000,size.height*0.4000000);
path_1.lineTo(size.width*0.5000000,size.height*0.4000000);
path_1.lineTo(size.width*0.5375000,size.height*0.5000000);
path_1.lineTo(size.width*0.3750000,size.height*0.5000000);
path_1.lineTo(size.width*0.3750000,size.height*0.4000000);
path_1.close();
canvas.drawPath(path_1, paint_1);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
大家可以自己试试:https://shapemaker.web.app/#/
一种实现方式是这样的。
class TriangleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final w = size.width;
final h = size.height;
final triangleWidth = 10;
final path = Path();
path.lineTo(0, 0);
path.lineTo(0, h);
path.lineTo(w, h);
path.lineTo(w - triangleWidth, 0);
path.close();
return path;
}
@override
bool shouldReclip(TriangleClipper oldClipper) => false;
}
并像这样使用它。
ClipPath(
clipper: TriangleClipper(),
child: Container(
padding: EdgeInsets.fromLTRB(4, 4, 14, 4), // 4 + triangleWidth for right padding
color: Colors.orange,
child: Text('A label'),
),
),
我需要在 flutter 中实现这个:
我尝试制作 Row
并将背景设置为 Text
来处理矩形,然后 ClipPath
来制作三角形。这样做的问题是边缘不精确(您可以在下图中的矩形和三角形之间看到一条细线),而且 ClipPath
具有固定大小,所以如果我想更改文本大小有些时候我将不得不再次 fine-tune 三角形。
这是我的代码:
class TriangleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.lineTo(0.0, size.height);
path.lineTo(size.width / 3, size.height);
path.close();
return path;
}
@override
bool shouldReclip(TriangleClipper oldClipper) => false;
}
Row(
children: [
Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
"a label",
),
),
),
ClipPath(
clipper: TriangleClipper(),
child: Container(
color: Colors.orange,
height: 23,
width: 20,
),
)
],
)
我虽然在 ClipPath
的 child 中使用 double.infinity
而不是固定大小会解决它,但这样做会使三角形消失(可能它变得太大了我不能'看不到它或落后于某些东西)。
解决这个问题的正确方法是什么?我想我可以使用 ClipPath
绘制梯形,但如何制作梯形以使其宽度适应 Text
的长度?
您可以试试下面的代码:
import 'dart:ui' as ui;
child: CustomPaint(
size: Size(WIDTH,(WIDTH*0.625).toDouble()), //You can Replace [WIDTH] with your desired width for Custom Paint and height will be calculated automatically
painter: RPSCustomPainter(),
),
class RPSCustomPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Paint paint_0 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 1;
paint_0.shader = ui.Gradient.linear(Offset(size.width*0.29,size.height*0.28),Offset(size.width*0.29,size.height*0.28),[Color(0xff7c1010),Color(0xffffffff)],[0.00,1.00]);
Path path_0 = Path();
path_0.moveTo(size.width*0.2937500,size.height*0.2780000);
canvas.drawPath(path_0, paint_0);
Paint paint_1 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 1;
Path path_1 = Path();
path_1.moveTo(size.width*0.3750000,size.height*0.4000000);
path_1.lineTo(size.width*0.5000000,size.height*0.4000000);
path_1.lineTo(size.width*0.5375000,size.height*0.5000000);
path_1.lineTo(size.width*0.3750000,size.height*0.5000000);
path_1.lineTo(size.width*0.3750000,size.height*0.4000000);
path_1.close();
canvas.drawPath(path_1, paint_1);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
大家可以自己试试:https://shapemaker.web.app/#/
一种实现方式是这样的。
class TriangleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final w = size.width;
final h = size.height;
final triangleWidth = 10;
final path = Path();
path.lineTo(0, 0);
path.lineTo(0, h);
path.lineTo(w, h);
path.lineTo(w - triangleWidth, 0);
path.close();
return path;
}
@override
bool shouldReclip(TriangleClipper oldClipper) => false;
}
并像这样使用它。
ClipPath(
clipper: TriangleClipper(),
child: Container(
padding: EdgeInsets.fromLTRB(4, 4, 14, 4), // 4 + triangleWidth for right padding
color: Colors.orange,
child: Text('A label'),
),
),