CustomPaint 使用淡入淡出效果擦除形状
CustomPaint Erase shape on hit with fade effect
我试图在单击画布时擦除我的圆圈。我想让它在第二次点击时再次出现。自动取款机我有这个:
class FadeEffect extends StatefulWidget {
const FadeEffect({Key? key}) : super(key: key);
@override
State<FadeEffect> createState() => _FadeEffectState();
}
class _FadeEffectState extends State<FadeEffect> {
double vOpacity = 1;
@override
void initState() {
super.initState();
Timer.periodic(const Duration(milliseconds: 100), (timer) {
vOpacity -= 0.1;
if (mounted) {
setState(() {
});
}
});
}
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
painter: MyPainter(vOpacity: vOpacity),
);
}
}
class MyPainter extends CustomPainter {
double vOpacity;
MyPainter({
required this.vOpacity
});
@override
void paint(Canvas canvas, Size size) {
canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height));
var paint = Paint()
..color = Color.fromRGBO(0, 0, 0, vOpacity)
..strokeWidth = 5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 300, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
@override
bool hitTest(Offset position) {
erase();
return true;
}
void erase() {
}
}
当我 运行 程序时,我将圆圈颜色的不透明度从 1 更改为 0(不知道当我调用 erase() 时该怎么做...)。另一个问题是我的圆圈一旦达到 0 不透明度就会再次出现。
P.S: 除了改变不透明度还有其他擦除方法吗?
如果您只想让圆圈消失而不产生任何影响,您可以使用 Visibility
小部件包裹 CustomPaint
来控制其子项的可见性。但是当你想要实现淡出效果时,你应该使用 AnimatedOpacity
小部件来动画任何不透明度的变化。
下面是一个 stand-alone 代码示例,我在其中演示了这两种方法。 UI 显示两个涂有 CustomPaint
的圆圈,当单击其 canvas 时,它们会消失并再次出现。第一个使用 AnimatedOpacity
而第二个使用 Visibility
小部件:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController controller = ScrollController();
double _opacity = 1.0;
bool _visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(
height: 300,
width: 300,
child: AnimatedOpacity(
duration: const Duration(
seconds: 3,
),
opacity: _opacity,
child: GestureDetector(
onTap: () {
setState(() {
_opacity = _opacity == 1 ? 0 : 1;
});
},
child: CustomPaint(
painter: MyPainter(),
),
),
),
),
SizedBox(
width: 300,
height: 300,
child: Visibility(
maintainInteractivity: true,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _visible,
child: GestureDetector(
onTap: () {
setState(() {
_visible = _visible ? false : true;
});
},
child: CustomPaint(
painter: MyPainter(),
),
),
),
),
const Text(
"Tap on the canvas, to make the circle appear or disappear",
),
],
),
);
}
}
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..color = Colors.black;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 100, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
我试图在单击画布时擦除我的圆圈。我想让它在第二次点击时再次出现。自动取款机我有这个:
class FadeEffect extends StatefulWidget {
const FadeEffect({Key? key}) : super(key: key);
@override
State<FadeEffect> createState() => _FadeEffectState();
}
class _FadeEffectState extends State<FadeEffect> {
double vOpacity = 1;
@override
void initState() {
super.initState();
Timer.periodic(const Duration(milliseconds: 100), (timer) {
vOpacity -= 0.1;
if (mounted) {
setState(() {
});
}
});
}
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
painter: MyPainter(vOpacity: vOpacity),
);
}
}
class MyPainter extends CustomPainter {
double vOpacity;
MyPainter({
required this.vOpacity
});
@override
void paint(Canvas canvas, Size size) {
canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height));
var paint = Paint()
..color = Color.fromRGBO(0, 0, 0, vOpacity)
..strokeWidth = 5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 300, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
@override
bool hitTest(Offset position) {
erase();
return true;
}
void erase() {
}
}
当我 运行 程序时,我将圆圈颜色的不透明度从 1 更改为 0(不知道当我调用 erase() 时该怎么做...)。另一个问题是我的圆圈一旦达到 0 不透明度就会再次出现。
P.S: 除了改变不透明度还有其他擦除方法吗?
如果您只想让圆圈消失而不产生任何影响,您可以使用 Visibility
小部件包裹 CustomPaint
来控制其子项的可见性。但是当你想要实现淡出效果时,你应该使用 AnimatedOpacity
小部件来动画任何不透明度的变化。
下面是一个 stand-alone 代码示例,我在其中演示了这两种方法。 UI 显示两个涂有 CustomPaint
的圆圈,当单击其 canvas 时,它们会消失并再次出现。第一个使用 AnimatedOpacity
而第二个使用 Visibility
小部件:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController controller = ScrollController();
double _opacity = 1.0;
bool _visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(
height: 300,
width: 300,
child: AnimatedOpacity(
duration: const Duration(
seconds: 3,
),
opacity: _opacity,
child: GestureDetector(
onTap: () {
setState(() {
_opacity = _opacity == 1 ? 0 : 1;
});
},
child: CustomPaint(
painter: MyPainter(),
),
),
),
),
SizedBox(
width: 300,
height: 300,
child: Visibility(
maintainInteractivity: true,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _visible,
child: GestureDetector(
onTap: () {
setState(() {
_visible = _visible ? false : true;
});
},
child: CustomPaint(
painter: MyPainter(),
),
),
),
),
const Text(
"Tap on the canvas, to make the circle appear or disappear",
),
],
),
);
}
}
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..color = Colors.black;
canvas.drawCircle(Offset(size.width / 2, size.height / 2), 100, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}