Reputation: 11
I put animated widgets that move from right to left on the home screen of my application. Here I drew circles using Canvas. I want to place images related to imageUrl inside these circles. Here, when I tried to place it with drawImage, the photos were not positioned exactly on top of the circles. Can you help me with this?
SizedBox(
height: Get.height / 2 + 20,
width: MediaQuery.of(context).size.width,
child: const WidgetSlider(children: [
Circle(
center: {"x": 40, "y": 100},
radius: 70,
color: Colors.green),
Circle(
center: {"x": -90, "y": 280},
radius: 65,
color: Colors.grey),
Circle(
center: {"x": 3, "y": 55},
radius: 55,
color: Colors.lime),
Circle(
center: {"x": -85, "y": 220},
radius: 80,
color: Colors.white),
Circle(
center: {"x": 0, "y": 130},
radius: 75,
color: Colors.black),
Circle(
center: {"x": 10, "y": 260},
radius: 75,
color: Colors.pink),
Circle(
center: {"x": -5, "y": 55},
radius: 55,
color: Colors.amber),
Circle(
center: {"x": -25, "y": 180},
radius: 55,
color: Colors.red),
]),
),
This is the animation I gave my widgets to slide from right to left.
import 'dart:async';
import 'package:flutter/material.dart';
class WidgetSlider extends StatefulWidget {
/// To pass children to this widget.
final List<Widget> children;
/// Spacing between each child.
/// Default spacing is 10.0
final double? spacing;
/// Sliding speed applied to widget every 100ms, for smooth transition lower values are recommended.
/// Default offset x = 10.0
final double? slidingSpeed;
/// Sliding direction.
/// Default is Axis.horizontal
final Axis? slideAxis;
/// Sliding child count
/// Default is 100m
final int? slideCount;
const WidgetSlider({
Key? key,
required this.children,
this.spacing,
this.slidingSpeed,
this.slideAxis,
this.slideCount,
}) : super(key: key);
@override
State<WidgetSlider> createState() => _WidgetSliderState();
}
class _WidgetSliderState extends State<WidgetSlider> {
late ScrollController _sliderController;
late Timer _sliderTimer;
final Duration _updateDuration = const Duration(milliseconds: 100);
final int _defaultSlideCount = 1000000000;
@override
void initState() {
assert(widget.children.length > 1);
_sliderController = ScrollController(initialScrollOffset: 0);
_sliderTimer = _assignTimer();
super.initState();
}
@override
void dispose() {
_sliderController.dispose();
_sliderTimer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AbsorbPointer(
absorbing: true,
child: ListView.separated(
controller: _sliderController,
shrinkWrap: true,
physics: null,
itemCount: widget.slideCount ?? _defaultSlideCount,
cacheExtent: MediaQuery.of(context).size.width,
scrollDirection: widget.slideAxis ?? Axis.horizontal,
itemBuilder: (context, index) {
return widget.children[index % widget.children.length];
},
separatorBuilder: (context, index) {
if (widget.slideAxis == null) {
return SizedBox(width: widget.spacing ?? 10);
}
return widget.slideAxis == Axis.horizontal
? SizedBox(width: widget.spacing ?? 10)
: SizedBox(height: widget.spacing ?? 10);
},
),
);
}
Timer _assignTimer() {
return Timer.periodic(
_updateDuration,
(_) {
_sliderController.animateTo(
_sliderController.offset + (widget.slidingSpeed ?? 10),
duration: _updateDuration,
curve: Curves.linear,
);
},
);
}
}
This is my Circle Class.
class Circle extends StatefulWidget {
final Map<String, double> center;
final double radius;
final Color color;
const Circle(
{Key? key,
required this.center,
required this.radius,
required this.color})
: super(key: key);
@override
_CircleState createState() => _CircleState();
}
class _CircleState extends State<Circle> with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width / 5,
MediaQuery.of(context).size.height),
painter: DrawCircle(
center: widget.center,
radius: widget.radius,
color: Colors.white,
));
}
}
My CustomPainter class is as follows.
class DrawCircle extends CustomPainter {
Map<String, double> center;
double radius;
Color color;
DrawCircle({
Key? key,
required this.center,
required this.radius,
required this.color,
});
@override
void paint(Canvas canvas, Size size) {
Paint brush = Paint()
..color = color
..strokeCap = StrokeCap.round
..style = PaintingStyle.fill
..strokeWidth = 30;
canvas.drawCircle(Offset(center["x"]!, center["y"]!), radius, brush);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
This is the shape I want to see as output.
This is the result I got. I couldn't add the images
Upvotes: 1
Views: 562
Reputation: 411
I would recommend using CircleAvatar instead of CustomPaint.
@override
Widget build(BuildContext context) {
return CircleAvatar(
radius: Size(MediaQuery.of(context).size.width / 5,
MediaQuery.of(context).size.height),
backgroundColor: white,
foregroundImage: NetworkImage(imageUrl)
);
}
This should solve your issue.
Upvotes: 0