Home > Blockchain >  Animated Curve Line - Flutter
Animated Curve Line - Flutter

Time:09-12

Is it possible to somehow do in flutter what is shown in the GIF?

enter image description here

And so that the starting point always displays a number (in what position this point is at the moment), in the range from 0-100.

CodePudding user response:

some packages that can provide this in a better and neat way

https://pub.dev/packages/syncfusion_flutter_charts https://pub.dev/packages/charts_flutter

CodePudding user response:

Try this (if you need explanation, comment below)

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

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin{

  late final AnimationController _controller = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 3)
  );

  late final Size size = const Size(400,400);

  late Path path = Path()
  ..moveTo(0, size.height -100)
  ..cubicTo(
    size.width/2-50, 0, 
    size.width/2 50, size.height, 
    size.width, 0
  );
  late PathAnimation pathAnimation = PathAnimation(path: path);

  @override
  void initState() {
    super.initState();
    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Material App Bar'),
        ),
        body: Center(
          child: ClipRect(
            child: AnimatedBuilder(
              animation: _controller,
              child: Container(
                height: 400,
                width: 400,
                decoration: BoxDecoration(
                  color: Colors.blue[100],
                  border: Border.all(
                    color: Colors.black,
                    width: 3,
                  )
                ),
              ),
              builder: (context, child) {
                return CustomPaint(
                  foregroundPainter: PathPainter(
                    animation: _controller.value,
                    pathAnimation: pathAnimation,
                  ),
                  child: child
                );
              }
            ),
          ),
        ),
      ),
    );
  }
}

class PathAnimation {

  final Path path;
  Path currentPath = Path();
  late final List<PathMetric> pathSegments;
  late final double totalLength;
  double currentLength = 0;
  int currentPathIndex = 0;

  PathAnimation({
    required this.path
  }) {
    pathSegments = path.computeMetrics().toList();
    totalLength = pathSegments.fold(0, (value, element) => value   element.length);
  }

  Path getCurrentPath(double animation) {
    while (animation > (currentLength   pathSegments[currentPathIndex].length) / totalLength) {
      double segmentLength = pathSegments[currentPathIndex].length;
      currentPath.addPath(
        pathSegments[currentPathIndex].extractPath(0, segmentLength),
        Offset.zero
      );
      currentPathIndex  ;
      currentLength  = segmentLength;
    }
    if (currentPathIndex >= pathSegments.length) return currentPath;
    double missingPartLength = animation - currentLength / totalLength;
    double newSegmentLength = pathSegments[currentPathIndex].length;
    return  
      currentPath..addPath(
      pathSegments[currentPathIndex].extractPath(0, missingPartLength * newSegmentLength),
      Offset.zero
    );
  }
}

class PathPainter extends CustomPainter{
  
  double animation;
  PathAnimation pathAnimation;

  PathPainter({
    required this.animation,
    required this.pathAnimation,
  });

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawPath(
      pathAnimation.getCurrentPath(animation),
      Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 3
      ..color = Colors.red
    );
  }

  @override
  bool shouldRepaint(PathPainter oldDelegate) {
    return animation != oldDelegate.animation;
  }
}
  • Related