[英]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.