I try to erase my circle when I click on the canva. I would like to make it appeat again on a second click. Atm I have this:
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() {
}
}
I change the opacity of the circle's color from 1 to 0 when I run the program (idk how to do it when I call erase() ...). The other problem is that my circle appears again once it reaches 0 opacity.
P.S: Is there an another way to erase than changing opacity ?
CodePudding user response:
If you just want to make the circle disappear without any affects you can wrap the CustomPaint
with the Visibility
widget which controls the Visibility of its child. But when you want to achieve a fading out affect you should use the AnimatedOpacity
widget which animates any opacity changes.
Below is a stand-alone code sample in which I demonstrated the two ways. The UI shows two circles painted with CustomPaint
which both disappear and appear again when its canvas is clicked. The first one uses AnimatedOpacity
whereas the second one uses the Visibility
widget:
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;
}
}