flutter实现进度条动画按钮,相信我你也可以变成光!

317 阅读1分钟

开源地址 github.com/7-bit-zhang…

效果图

9cf3500ee058a8e3f38aaac5d5d4fd1d.gif

圆形进度条

首先我们需要先绘制一个圆形

class CirclePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    // Draw the circle
    canvas.drawCircle(
      Offset(size.width / 2, size.height / 2),
      size.width / 2,
      paint,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

开始绘制曲线波浪

Paint wavePaints=Paint()..color = Colors.blue
Path paths =Path()
for (double i = -waveLength / 4; i <= waveLength * 1.5; i++) {
        double dx = i;
        double dy;
        dy =
            sin((i / waveLength * sindy * pi) + (waveAnimationValue * 2 * pi)) *
                    waveLength +
                centerY;
        if (i == -waveLength / 4) {
          paths[index].moveTo(dx, dy);
        } else {
          paths[index].lineTo(dx, dy);
        }
      }
paths.lineTo(size.width * 3, size.height);
paths.lineTo(-waveLength / 4, size.height);
paths.close();
canvas.drawPath(paths, wavePaints);

需要绘制多层波浪动画

 double waveLength = size.width;
    double radius = size.width / 2;
    double centerY = size.height * (1 - progress);
    Paint circlePaint = Paint()..color = backgroundColor;
    List<Paint> wavePaints = [];
    List<Path> paths = [];
    double dynamicWaveHeight = waveHeight * progress;
    if (progress == 1) {
      dynamicWaveHeight = 0;
    }

    /// 波浪画笔
    for (var index = 0; index < colorsWave.length; index++) {
      wavePaints.add(Paint()..color = colorsWave[index]);
      paths.add(Path());
    }

    double sindy = 2.5;
    //使波浪看起来有层叠感
    if (paths.length == 1) {
      sindy = 1.5;
    } else if (paths.length == 2) {
      sindy = 2.0;
    }

    /// 绘制波浪
    for (var index = 0; index < paths.length; index++) {
      for (double i = -waveLength / 4; i <= waveLength * 1.5; i++) {
        double dx = i;
        double dy;
        dy =
            sin((i / waveLength * sindy * pi) + (waveAnimationValue * 2 * pi)) *
                    dynamicWaveHeight +
                centerY;
        if (index == 1) {
          dy = sin((i / waveLength * sindy * pi) +
                      (waveAnimationValue * 2 * pi) +
                      pi / 2) *
                  dynamicWaveHeight +
              centerY;
        } else if (index == 2) {
          dy = sin((i / waveLength * sindy * pi) +
                      (waveAnimationValue * 2 * pi) +
                      pi) *
                  dynamicWaveHeight +
              centerY;
        }
        if (i == -waveLength / 4) {
          paths[index].moveTo(dx, dy);
        } else {
          paths[index].lineTo(dx, dy);
        }
      }
      sindy -= .5;
    }
    for (var index = 0; index < paths.length; index++) {
      paths[index].lineTo(size.width * 3, size.height);
      paths[index].lineTo(-waveLength / 4, size.height);
      paths[index].close();
    }

    // 绘制圆形背景
    canvas.drawCircle(Offset(radius, radius), radius, circlePaint);

    // // 裁剪圆形区域
    canvas.clipPath(Path()
      ..addOval(
          Rect.fromCircle(center: Offset(radius, radius), radius: radius)));
    // 创建矩形背景
    Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
    canvas.clipPath(Path()
      ..addOval(
          Rect.fromCircle(center: Offset(radius, radius), radius: radius)));
    // 绘制背景矩形
    canvas.drawRect(rect, circlePaint);
    // 绘制多层波浪
    for (var i = 0; i < wavePaints.length; i++) {
      canvas.drawPath(paths[i], wavePaints[i]);
    }