项目里有个拍照的需求,大概是这样子的
实现这个很简单,就是底部是照相机,上面再弄个遮罩把相机给遮起来
我们先实现相机的展示
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final top = width*2/3 - width/2;
final bottom = width*4/3 - width/2;
return Material(
color: Colors.white,
child: Stack(
children: [
Column(
children: [
SafeArea(child: Align(
alignment: Alignment(0.9, 0),
child: IconButton(
icon: Icon(Icons.clear_outlined, color: Colors.blue,),
onPressed: ()=> Navigator.pop(context),
),
), top: true,),
Container(
// color: Colors.red,
height: width,
width: size.width,
child: Stack(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 0.125*width),
height: width,
child: initialState ?
CameraPreview(controller) : const SizedBox.expand(),
),
],
),
),
Center(
child: Text('请保持头像在圆圈内', textAlign: TextAlign.center,style: TextStyle(color: Colors.grey, fontSize: 18, fontWeight: FontWeight.w500)),
),
SafeArea(child: SizedBox(), bottom: false,)
],
),
],
),
);
}
运行代码
Stack(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 0.125*width),
height: width,
child: initialState ?
CameraPreview(controller) : const SizedBox.expand(),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 0.125*width),
height: width,
child: CustomPaint(
size: Size(width*0.75, width),
painter: CiclePainter(),
),
),
],
)
我们需要在相机上添加一个圆形的镂空的widget
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
// 创建画笔
canvas.translate(0, 0);
final Paint paint = Paint();
paint.color = Colors.white;
Path path = Path();
path
..moveTo(0, 0)
..lineTo(width, 0)
..lineTo(width, height)
..lineTo(0,height)
..close();
var pathOval =Path()..addOval(Rect.fromCenter(center: Offset(width/2, height/2),width: width,height: width));
canvas.drawPath(Path.combine(PathOperation.difference, path, pathOval), paint);
}
大概步骤就是先画一个和相机一样大小的矩形,在镂空一个矩形内的圆。
Path.combine(PathOperation.difference, path, pathOval)
我理解是这个方法可以将两个路径相交的地方抵消掉,最后就变成这样
项目链接
[github.com/dongzhengga…]