I want to make a curved path between widgets on my website, like a story timeline. I have managed to draw the curved paths, however, the problem arises when resizing the page as they move and start overlapping with the widgets.
Currently, I am using the following code:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:sales_pitch/views/1.dart';
import 'package:sales_pitch/views/2.dart';
import 'package:sales_pitch/views/4.dart';
import 'package:sales_pitch/views/5.dart';
import 'package:sales_pitch/views/6.dart';
import 'package:sales_pitch/views/landing.dart';
import 'package:sales_pitch/widgets/curved_painter.dart';
import '../constants/assets.dart';
import '3.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
List<Widget> sections = [
const LandingView(),
const FirstView(),
const SecondView(),
const ThirdView(),
const FourthView(),
const FifthView(),
const SixthView(),
const SizedBox(height: 250),
];
//* I have also tried using positioned images however these also moved and screwed up the layout
List<Widget> lines = [
Positioned(
top: size.height * 0.95,
left: 0,
right: 0,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: size.width * 0.18,
child: Image.asset(
AppAssets.getAppPath(1),
fit: BoxFit.fitWidth,
),
),
),
),
Positioned(
top: size.height * 1.42,
left: size.width * 0.2,
child: Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: size.width * 0.3,
child: Image.asset(
AppAssets.getAppPath(2),
fit: BoxFit.fitWidth,
),
),
),
),
Positioned(
top: size.height * 1.58,
right: size.width * 0.2,
child: Align(
alignment: Alignment.centerRight,
child: SizedBox(
width: size.width * 0.35,
child: Image.asset(
AppAssets.getAppPath(3),
fit: BoxFit.fitWidth,
),
),
),
),
Positioned(
top: size.height * 1.75,
left: size.width * 0.15,
right: size.width * 0.1,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: size.height * 0.2,
child: Image.asset(
AppAssets.getAppPath(4),
fit: BoxFit.fitHeight,
),
),
),
),
Positioned(
top: size.height * 2.5,
left: 0,
right: 0,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: size.height * 0.26,
child: Image.asset(
AppAssets.getAppPath(5),
fit: BoxFit.fitHeight,
),
),
),
),
Positioned(
top: size.height * 3.2,
left: size.width * 0.4,
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
height: size.height * 0.3,
child: Image.asset(
AppAssets.getAppPath(6),
fit: BoxFit.fitHeight,
),
),
),
),
Positioned(
top: size.height * 4,
right: size.width * 0.1,
child: Align(
alignment: Alignment.centerRight,
child: SizedBox(
height: size.height * 0.45,
child: Image.asset(
AppAssets.getAppPath(7),
fit: BoxFit.fitHeight,
),
),
),
),
Positioned(
top: size.height * 5.4,
left: 0,
right: 0,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: size.height * 0.2,
child: Image.asset(
AppAssets.getAppPath(8),
fit: BoxFit.fitHeight,
),
),
),
),
];
return Scaffold(
body: SingleChildScrollView(
child: Stack(
clipBehavior: Clip.none,
children: [
SizedBox(height: size.height * (sections.length / 2)),
//...lines,
//TODO: add the new lines to a list to cleanup code
//* First Line
Positioned(
top: size.height * 0.95,
left: size.width * 0.35,
height: size.height * 0.23,
width: size.width * 0.15,
child: CustomPaint(
painter: CurvePainter(),
willChange: true,
child: Container(),
),
),
//* Second Line
Positioned(
top: size.height * 1.35,
left: size.width * 0.15,
height: size.height * 0.12,
width: size.width * 0.35,
child: Transform(
transform: Matrix4.rotationY(pi),
alignment: Alignment.center,
child: CustomPaint(
painter: CurvePainter(),
willChange: true,
child: Container(),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start, children: sections),
],
),
),
);
}
}
I have also tried using images exported from Figma and positioning them as needed, however, the same issue arises. I would also prefer the lines in code so they can easily be changed in the future.
AFAIK
Row
widget.Column
+ Row
below line with text and lorem block.It's easier to do it with rows, rather than calculate it with positioned. Is see overlapping only at 1st line, but it can also be done with Row\Column