簡體   English   中英

如何制作具有波紋效果的按鈕?

[英]How to make a button with ripple effect?

在此處輸入圖像描述

這就是我所擁有的

Positioned(
    bottom: 15,
    child: InkWell(
    onTap: () {},
    child: Material(
        type: MaterialType.circle,
        color: Color(0xFF246DE9),
        child: Padding(
        padding: const EdgeInsets.all(24),
        child: Text(
            'GO',
            style: TextStyle(
            fontSize: 25,
            color: Colors.white,
            ),
        ),
        ),
    ),
    ),
),
Positioned(
    bottom: 30,
    child: CustomPaint(
    size: Size(50, 50),
    painter: CirclePainter(),
    ),
),

圓圈畫家

class CirclePainter extends CustomPainter {
  final _paint = Paint()
    ..color = Colors.white
    ..strokeWidth = 2
    ..style = PaintingStyle.stroke;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawOval(
      Rect.fromLTWH(0, 0, size.width, size.height),
      _paint,
    );
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

在此處輸入圖像描述

我創建了一個堆棧,並嘗試將白色圓圈和“GO”按鈕堆疊在一起,但我不知道如何創建該動畫。 白色圓圈的大小需要逐漸增加,它必須變得不可見。

任何人都可以幫忙嗎?

我准備了一個漣漪課程。 靈感來自https://pub.dev/packages/ripple_animation 請檢查如下。 在這里,請根據您的子小部件更新minRadius

import 'dart:async';

import 'package:flutter/material.dart';

/// You can use whatever widget as a [child], when you don't need to provide any
/// [child], just provide an empty Container().
/// [delay] is using a [Timer] for delaying the animation, it's zero by default.
/// You can set [repeat] to true for making a paulsing effect.
class RippleAnimation extends StatefulWidget {
  final Widget child;
  final Duration delay;
  final double minRadius;
  final Color color;
  final int ripplesCount;
  final Duration duration;
  final bool repeat;

  const RippleAnimation({
    required this.child,
    required this.color,
    Key? key,
    this.delay = const Duration(milliseconds: 0),
    this.repeat = false,
    this.minRadius = 25,
    this.ripplesCount = 5,
    this.duration = const Duration(milliseconds: 2300),
  }) : super(key: key);

  @override
  _RippleAnimationState createState() => _RippleAnimationState();
}

class _RippleAnimationState extends State<RippleAnimation>
    with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    _controller = AnimationController(
      duration: widget.duration,
      vsync: this,
      lowerBound: 0.7,
      upperBound: 1.0
    );

    // repeating or just forwarding the animation once.
    Timer(widget.delay, () {
      widget.repeat ? _controller?.repeat() : _controller?.forward();
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      foregroundPainter: CirclePainter(
        _controller,
        color: widget.color ?? Colors.black,
        minRadius: 25,
        wavesCount: widget.ripplesCount,
      ),
      child: widget.child,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

// Creating a Circular painter for clipping the rects and creating circle shapes
class CirclePainter extends CustomPainter {
  CirclePainter(
      this._animation, {
        required this.minRadius,
        this.wavesCount,
        required this.color,
      }) : super(repaint: _animation);
  final Color color;
  final double minRadius;
  final wavesCount;
  final Animation<double> _animation;
  final _paint = Paint()
    ..color = Colors.white
    ..strokeWidth = 2
    ..style = PaintingStyle.stroke;
  @override
  void paint(Canvas canvas, Size size) {
    final Rect rect = Rect.fromLTRB(0.0, 0.0, 100, 100);
    for (int wave = 0; wave <= wavesCount; wave++) {
      circle(canvas, rect, minRadius, wave, _animation.value, wavesCount);
    }
  }

  // animating the opacity according to min radius and waves count.
  void circle(Canvas canvas, Rect rect, double minRadius, int wave,
      double value, int length) {
    Color _color;
    double r;
    if (wave != 0) {
      double opacity = (1 - ((wave - 1) / length) - value).clamp(0.0, 1.0);
      _color = color.withOpacity(opacity);

      r = minRadius * (1 + ((wave * value))) * value;
      print("value >> r >> $r min radius >> $minRadius value>> $value");
      final Paint paint = Paint()..color = _color;
      paint..strokeWidth = 2
        ..style = PaintingStyle.stroke;
      canvas.drawCircle(rect.center, r, paint);
    }
  }

  @override
  bool shouldRepaint(CirclePainter oldDelegate) => true;
}

例子:

RippleAnimation(
              ripplesCount: 1,
              repeat: true,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.blue,
                  shape: BoxShape.circle
                ),
                width: 100,
                height: 100,
                child: Center(
                  child: Text(
                    'GO',
                    style: TextStyle(
                      fontSize: 25,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
              color: Colors.white)

如果它不適合你,請告訴我。 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM