Files
flutter_wisetronic/lib/widgets/general/popup_animation_widget.dart

69 lines
2.0 KiB
Dart

import 'package:flutter/material.dart';
// ignore: must_be_immutable
class PopupAnimationWidget extends AnimatedWidget {
final GlobalKey stackKey;
final GlobalKey startKey;
final Color color;
final Widget child;
final Offset popupOffset;
final Animation<double> animation;
PopupAnimationWidget({
required this.animation,
required this.stackKey,
required this.startKey,
required this.child,
this.color = Colors.yellow,
this.popupOffset = Offset.zero,
}) : super(listenable: animation);
Offset? _startOffset;
Offset _offset = Offset.zero;
@override
Widget build(BuildContext context) {
_calAnimation();
final Animation<double> opacityAnimation = Tween<double>(begin: 0, end: 1)
.animate(CurvedAnimation(
parent: animation, curve: Interval(0, 0.4, curve: Curves.ease)));
_offset =
Offset(_startOffset!.dx, _startOffset!.dy - opacityAnimation.value * 80);
return Positioned(
left: _offset.dx,
top: _offset.dy,
child: Opacity(
opacity: opacityAnimation.value,
child: ScaleTransition(
alignment: Alignment.bottomCenter,
scale: opacityAnimation,
child: Container(
child: child,
),
),
),
);
}
void _calAnimation() {
if (_startOffset == null) {
final RenderBox stackBox = stackKey.currentContext!.findRenderObject()! as RenderBox;
final Offset stackBoxOffset = stackBox.globalToLocal(Offset.zero);
final EdgeInsets startMargin = _margin(startKey);
final RenderBox startBox = startKey.currentContext!.findRenderObject()! as RenderBox;
_startOffset = startBox.localToGlobal(Offset(
startMargin.left + popupOffset.dx,
stackBoxOffset.dy + startMargin.top + popupOffset.dy));
}
}
EdgeInsets _margin(GlobalKey key) {
final Widget widget = key.currentContext!.widget;
final mg = (widget is Container) ? widget.margin : null;
return mg is EdgeInsets ? mg : EdgeInsets.zero;
}
}