答案 0 :(得分:1)
使用 Figma,为共享的图像创建一个矢量。
以 svg 格式导出矢量。
您可以通过两种方式打开 svg 文件以获取其内容:
i) 通过浏览器打开并转到检查元素
ii) 使用记事本或记事本++打开文件
以下是步骤 1
中创建的 svg 的内容<svg width="474" height="157" viewBox="0 0 474 157" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M45 141L1 156H473L444 149L420 141L398 126L378 106L357 80L334 53L318 35L299 17L270 6L236 1H198L170 11L147 30L124 53L102 80L84 100L65 126L45 141Z" stroke="black"/>
</svg>
M45 141L1 156H473L444 149L420 141L398 126L378 106L357 80L334 53L318 35L299 17L270 6L236 1H198L170 11L147 30L124 53L102 80L84 100L65 126L45 141Z
import 'package:flutter/material.dart';
class CustomPath extends StatefulWidget {
@override
_CustomPathState createState() => _CustomPathState();
}
class _CustomPathState extends State<CustomPath> {
@override
Widget build(BuildContext context) {
return Scaffold(
);
}
}
在本课程中,您将只做两件事:
ClipPath
小部件CustomClipper
,并将添加到 clipper
小部件的 ClipPath
属性中。BezierClipper
,其方法为 shouldReclip()
。class BezierClipper extends CustomClipper<Path> {
@override
bool shouldReclip(oldClipper) => false;
}
class BezierClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
final double _xScaling = size.width / 414;
final double _yScaling = size.height / 896;
path.lineTo(45 * _xScaling, 141 * _yScaling);
path.cubicTo(
45 * _xScaling,
141 * _yScaling,
1 * _xScaling,
156 * _yScaling,
1 * _xScaling,
156 * _yScaling,
);
path.cubicTo(
1 * _xScaling,
156 * _yScaling,
473 * _xScaling,
156 * _yScaling,
473 * _xScaling,
156 * _yScaling,
);
path.cubicTo(
473 * _xScaling,
156 * _yScaling,
444 * _xScaling,
149 * _yScaling,
444 * _xScaling,
149 * _yScaling,
);
path.cubicTo(
444 * _xScaling,
149 * _yScaling,
420 * _xScaling,
141 * _yScaling,
420 * _xScaling,
141 * _yScaling,
);
path.cubicTo(
420 * _xScaling,
141 * _yScaling,
398 * _xScaling,
126 * _yScaling,
398 * _xScaling,
126 * _yScaling,
);
path.cubicTo(
398 * _xScaling,
126 * _yScaling,
378 * _xScaling,
106 * _yScaling,
378 * _xScaling,
106 * _yScaling,
);
path.cubicTo(
378 * _xScaling,
106 * _yScaling,
357 * _xScaling,
80 * _yScaling,
357 * _xScaling,
80 * _yScaling,
);
path.cubicTo(
357 * _xScaling,
80 * _yScaling,
334 * _xScaling,
53 * _yScaling,
334 * _xScaling,
53 * _yScaling,
);
path.cubicTo(
334 * _xScaling,
53 * _yScaling,
318 * _xScaling,
35 * _yScaling,
318 * _xScaling,
35 * _yScaling,
);
path.cubicTo(
318 * _xScaling,
35 * _yScaling,
299 * _xScaling,
17 * _yScaling,
299 * _xScaling,
17 * _yScaling,
);
path.cubicTo(
299 * _xScaling,
17 * _yScaling,
270 * _xScaling,
6 * _yScaling,
270 * _xScaling,
6 * _yScaling,
);
path.cubicTo(
270 * _xScaling,
6 * _yScaling,
236 * _xScaling,
1 * _yScaling,
236 * _xScaling,
1 * _yScaling,
);
path.cubicTo(
236 * _xScaling,
1 * _yScaling,
198 * _xScaling,
1 * _yScaling,
198 * _xScaling,
1 * _yScaling,
);
path.cubicTo(
198 * _xScaling,
1 * _yScaling,
170 * _xScaling,
11 * _yScaling,
170 * _xScaling,
11 * _yScaling,
);
path.cubicTo(
170 * _xScaling,
11 * _yScaling,
147 * _xScaling,
30 * _yScaling,
147 * _xScaling,
30 * _yScaling,
);
path.cubicTo(
147 * _xScaling,
30 * _yScaling,
124 * _xScaling,
53 * _yScaling,
124 * _xScaling,
53 * _yScaling,
);
path.cubicTo(
124 * _xScaling,
53 * _yScaling,
102 * _xScaling,
80 * _yScaling,
102 * _xScaling,
80 * _yScaling,
);
path.cubicTo(
102 * _xScaling,
80 * _yScaling,
84 * _xScaling,
100 * _yScaling,
84 * _xScaling,
100 * _yScaling,
);
path.cubicTo(
84 * _xScaling,
100 * _yScaling,
65 * _xScaling,
126 * _yScaling,
65 * _xScaling,
126 * _yScaling,
);
path.cubicTo(
65 * _xScaling,
126 * _yScaling,
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
);
path.cubicTo(
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
);
return path;
}
@override
bool shouldReclip(oldClipper) => true;
}
添加将裁剪 CustomClipper 的 ClipPath,在本例中称为 BezierClipper
然后添加一个 Container
作为它的子元素,它将符合新的形状。
像这样:
class _CustomPathState extends State<CustomPath> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ClipPath(
clipper: BezierClipper(),
child:
Container(alignment: Alignment.center, color: Colors.black),
));
}
}
import 'package:flutter/material.dart';
class CustomPath extends StatefulWidget {
@override
_CustomPathState createState() => _CustomPathState();
}
class _CustomPathState extends State<CustomPath> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ClipPath(
clipper: BezierClipper(),
child:
Container(alignment: Alignment.center, color: Colors.black),
));
}
}
class BezierClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
final double _xScaling = size.width / 414;
final double _yScaling = size.height / 896;
path.lineTo(45 * _xScaling, 141 * _yScaling);
path.cubicTo(
45 * _xScaling,
141 * _yScaling,
1 * _xScaling,
156 * _yScaling,
1 * _xScaling,
156 * _yScaling,
);
path.cubicTo(
1 * _xScaling,
156 * _yScaling,
473 * _xScaling,
156 * _yScaling,
473 * _xScaling,
156 * _yScaling,
);
path.cubicTo(
473 * _xScaling,
156 * _yScaling,
444 * _xScaling,
149 * _yScaling,
444 * _xScaling,
149 * _yScaling,
);
path.cubicTo(
444 * _xScaling,
149 * _yScaling,
420 * _xScaling,
141 * _yScaling,
420 * _xScaling,
141 * _yScaling,
);
path.cubicTo(
420 * _xScaling,
141 * _yScaling,
398 * _xScaling,
126 * _yScaling,
398 * _xScaling,
126 * _yScaling,
);
path.cubicTo(
398 * _xScaling,
126 * _yScaling,
378 * _xScaling,
106 * _yScaling,
378 * _xScaling,
106 * _yScaling,
);
path.cubicTo(
378 * _xScaling,
106 * _yScaling,
357 * _xScaling,
80 * _yScaling,
357 * _xScaling,
80 * _yScaling,
);
path.cubicTo(
357 * _xScaling,
80 * _yScaling,
334 * _xScaling,
53 * _yScaling,
334 * _xScaling,
53 * _yScaling,
);
path.cubicTo(
334 * _xScaling,
53 * _yScaling,
318 * _xScaling,
35 * _yScaling,
318 * _xScaling,
35 * _yScaling,
);
path.cubicTo(
318 * _xScaling,
35 * _yScaling,
299 * _xScaling,
17 * _yScaling,
299 * _xScaling,
17 * _yScaling,
);
path.cubicTo(
299 * _xScaling,
17 * _yScaling,
270 * _xScaling,
6 * _yScaling,
270 * _xScaling,
6 * _yScaling,
);
path.cubicTo(
270 * _xScaling,
6 * _yScaling,
236 * _xScaling,
1 * _yScaling,
236 * _xScaling,
1 * _yScaling,
);
path.cubicTo(
236 * _xScaling,
1 * _yScaling,
198 * _xScaling,
1 * _yScaling,
198 * _xScaling,
1 * _yScaling,
);
path.cubicTo(
198 * _xScaling,
1 * _yScaling,
170 * _xScaling,
11 * _yScaling,
170 * _xScaling,
11 * _yScaling,
);
path.cubicTo(
170 * _xScaling,
11 * _yScaling,
147 * _xScaling,
30 * _yScaling,
147 * _xScaling,
30 * _yScaling,
);
path.cubicTo(
147 * _xScaling,
30 * _yScaling,
124 * _xScaling,
53 * _yScaling,
124 * _xScaling,
53 * _yScaling,
);
path.cubicTo(
124 * _xScaling,
53 * _yScaling,
102 * _xScaling,
80 * _yScaling,
102 * _xScaling,
80 * _yScaling,
);
path.cubicTo(
102 * _xScaling,
80 * _yScaling,
84 * _xScaling,
100 * _yScaling,
84 * _xScaling,
100 * _yScaling,
);
path.cubicTo(
84 * _xScaling,
100 * _yScaling,
65 * _xScaling,
126 * _yScaling,
65 * _xScaling,
126 * _yScaling,
);
path.cubicTo(
65 * _xScaling,
126 * _yScaling,
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
);
path.cubicTo(
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
45 * _xScaling,
141 * _yScaling,
);
return path;
}
@override
bool shouldReclip(oldClipper) => true;
}
答案 1 :(得分:0)
创建一个 StatelessWidget,比如接受直径的 MyArc。
class MyArc extends StatelessWidget {
final double diameter;
const MyArc({Key key, this.diameter = 200}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: MyPainter(),
size: Size(diameter, diameter),
);
}
}
// This is the Painter class
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..color = Colors.blue;
canvas.drawArc(
Rect.fromCenter(
center: Offset(size.height / 2, size.width / 2),
height: size.height,
width: size.width,
),
math.pi,
math.pi,
false,
paint,
);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
用法:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: MyArc(diameter: 300),
);
}
答案 2 :(得分:0)
这种形状需要贝塞尔曲线来制作。
如果您可以将此图像创建为 SVG,则可以使用 this tool 创建可在 Flutter 中使用的 ClipPath。
有关如何使用 ClipPath 的一些阅读:https://medium.com/flutterdevs/custom-clipping-in-flutter-8aa0631ef19b