You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mohemm-flutter-app/lib/widgets/glowy_borders/glowy_borders.dart

151 lines
4.8 KiB
Dart

library glowy_borderspertino.dart;
import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
class AnimatedGradientBorder extends StatefulWidget {
const AnimatedGradientBorder(
{Key? key,
required this.child,
required this.gradientColors,
required this.borderRadius,
this.animationTime,
this.borderSize,
this.animationProgress,
this.stretchAlongAxis = false,
this.stretchAxis = Axis.horizontal});
final Widget child;
final double? borderSize;
final List<Color> gradientColors;
final BorderRadiusGeometry borderRadius;
final int? animationTime;
final double? animationProgress;
final bool stretchAlongAxis;
final Axis stretchAxis;
@override
State<StatefulWidget> createState() => AnimatedGradientState();
}
class AnimatedGradientState extends State<AnimatedGradientBorder> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation _angleAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(seconds: widget.animationTime ?? 2));
_controller.addListener(() => setState(() {}));
_angleAnimation = Tween<double>(begin: 0.1, end: 2 * math.pi).animate(_controller);
if (widget.animationProgress != null) {
_controller.forward();
} else {
_controller.repeat();
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
void didUpdateWidget(covariant AnimatedGradientBorder oldWidget) {
super.didUpdateWidget(oldWidget);
double? animateTo = widget.animationProgress;
if (animateTo != null) {
_controller.animateTo(animateTo);
} else {
_controller.repeat();
}
}
@override
Widget build(BuildContext context) {
double? negativeMargin = -1.0 * (widget.borderSize ?? 0);
return Container(
padding: EdgeInsets.all(widget.borderSize ?? 0),
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: MyColors.kWhiteColor,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Stack(alignment: Alignment.center, clipBehavior: Clip.none, children: [
Positioned(
top: negativeMargin,
left: negativeMargin,
right: negativeMargin,
bottom: negativeMargin,
child: AnimatedGradientContainer(
gradientColors: widget.gradientColors,
borderRadius: widget.borderRadius,
gradientAngle: _angleAnimation.value,
)),
widget.child,
// BackdropFilter(
// filter: ImageFilter.blur(sigmaX: widget.glowSize ?? 0, sigmaY: widget.glowSize ?? 0),
// child: Stack(
// alignment: Alignment.center,
// clipBehavior: Clip.none,
// children: [
// Positioned(
// top: negativeMargin,
// right: negativeMargin,
// left: negativeMargin,
// bottom: negativeMargin,
// child: AnimatedGradientContainer(
// gradientColors: widget.gradientColors,
// borderRadius: widget.borderRadius,
// gradientAngle: _angleAnimation.value,
// )),
// if (widget.stretchAlongAxis)
// SizedBox(
// width: widget.stretchAxis == Axis.horizontal ? double.infinity : null,
// height: widget.stretchAxis == Axis.vertical ? double.infinity : null,
// child: widget.child,
// )
// else
// widget.child,
// ],
// ),
// ),
]),
);
}
}
class AnimatedGradientContainer extends StatelessWidget {
const AnimatedGradientContainer({Key? key, required this.gradientColors, required this.gradientAngle, required this.borderRadius});
final List<Color> gradientColors;
final double gradientAngle;
final BorderRadiusGeometry borderRadius;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: borderRadius,
gradient: SweepGradient(
colors: [...gradientColors, ...gradientColors.reversed], stops: _generateColorStops([...gradientColors, ...gradientColors.reversed]), transform: GradientRotation(gradientAngle))));
}
List<double> _generateColorStops(List<dynamic> colors) {
return colors.asMap().entries.map((entry) {
double percentageStop = entry.key / colors.length;
return percentageStop;
}).toList();
}
}