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.
151 lines
4.8 KiB
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();
|
|
}
|
|
}
|