gpt4 book ai didi

flutter CustomPainter - 如何在线路径中切出一个洞

转载 作者:行者123 更新时间:2023-12-05 05:46:58 24 4
gpt4 key购买 nike

我有一个绘制椭圆形的 CustomPaint

我想在一个特定的位置切出一个洞,我还不知道它是如何工作的。

我试过:

canvas.drawPath(
Path.combine(PathOperation.difference, ovalPath, holePath),
ovalPaint,
);

但这并没有解决问题,而是给了我以下结果:

enter image description here

但这就是我想要实现的: enter image description here

这个椭圆形只是一个例子,“真正的”定制油漆会变得更加复杂,我需要的不仅仅是一个切口。所以只画几行不是一个选择。我想先定义路径,然后应用剪切(甚至反向剪切)来获得孔。

这可能吗?

这是我所拥有的一个完整的工作示例:

import 'package:flutter/material.dart';
import 'dart:math';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: const Scaffold(
body: Center(
child: OvalCustomPaint(),
),
),
);
}
}

class OvalCustomPaint extends StatelessWidget {
const OvalCustomPaint({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Center(
child: LayoutBuilder(
builder: (context, constraints) {
return Center(
child: CustomPaint(
painter: _Painter(),
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
),
),
);
},
),
);
}
}

class _Painter extends CustomPainter {

@override
void paint(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
const curveRadius = 50.0;
const legLength = 150.0;
canvas.rotate(pi/2);


final ovalPaint = Paint()
..color = Colors.blue
..strokeWidth = 2.5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;

const fixPoint = Offset.zero;

//* OVAL LINE
final ovalPath = Path()..moveTo(fixPoint.dx, fixPoint.dy);
ovalPath.relativeArcToPoint(
const Offset(curveRadius * 2, 0),
radius: const Radius.circular(curveRadius),
);
ovalPath.relativeLineTo(0, legLength);
ovalPath.relativeArcToPoint(
const Offset(-curveRadius * 2, 0),
radius: const Radius.circular(curveRadius),
);
ovalPath.relativeLineTo(0, -legLength);


//* CLP HOLE
final holePath = Path();
holePath.addArc(Rect.fromCircle(center: fixPoint, radius: 13), 0, 2 * pi);


canvas.drawPath(
Path.combine(PathOperation.difference, ovalPath, holePath),
ovalPaint,
);
}

@override
bool shouldRepaint(_Painter oldDelegate) => false;

}

最佳答案

好的,我找到了解决方案。

我创建了一个大小与 CustomPainter 区域相同的矩形路径,并用切口孔路径建立了差异。

创建了一个剪切模板:

    final rectWithCutout = Path.combine(
PathOperation.difference,
Path()
..addRect(
Rect.fromCenter(
center: Offset.zero,
width: size.width,
height: size.height,
),
),
holePath);

enter image description here

我可以用它来剪辑 Canvas :canvas.clipPath(rectWithCutout);

最终结果:

enter image description here

这又是完整的工作代码示例:

import 'dart:math';

import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: const Scaffold(
body: Center(
child: OvalCustomPaint(),
),
),
);
}
}

class OvalCustomPaint extends StatelessWidget {
const OvalCustomPaint({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Center(
child: LayoutBuilder(
builder: (context, constraints) {
return Center(
child: CustomPaint(
painter: _Painter(),
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
),
),
);
},
),
);
}
}

class _Painter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
const curveRadius = 40.0;
const legLength = 130.0;
canvas.rotate(pi / 2);

final ovalPaint = Paint()
..color = Colors.blue
..strokeWidth = 2.5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;

const fixPoint = Offset.zero;

//* OVAL LINE
final ovalPath = Path()..moveTo(fixPoint.dx, fixPoint.dy);
ovalPath.relativeArcToPoint(
const Offset(curveRadius * 2, 0),
radius: const Radius.circular(curveRadius),
);
ovalPath.relativeLineTo(0, legLength);
ovalPath.relativeArcToPoint(
const Offset(-curveRadius * 2, 0),
radius: const Radius.circular(curveRadius),
);
ovalPath.relativeLineTo(0, -legLength);

//* CLIP HOLE
final holePath = Path();
holePath.addArc(Rect.fromCircle(center: fixPoint, radius: 13), 0, 2 * pi);

final rectWithCutout = Path.combine(
PathOperation.difference,
Path()
..addRect(
Rect.fromCenter(
center: Offset.zero,
width: size.width,
height: size.height,
),
),
holePath);

canvas.clipPath(rectWithCutout);

canvas.drawPath(
ovalPath,
ovalPaint,
);
}

@override
bool shouldRepaint(_Painter oldDelegate) => false;
}

关于flutter CustomPainter - 如何在线路径中切出一个洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71108148/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com