diff --git a/example/android/app/src/main/gen/com/example/example/BuildConfig.java b/example/android/app/src/main/gen/com/example/example/BuildConfig.java
new file mode 100644
index 0000000..a0c467d
--- /dev/null
+++ b/example/android/app/src/main/gen/com/example/example/BuildConfig.java
@@ -0,0 +1,8 @@
+/*___Generated_by_IDEA___*/
+
+package com.example.example;
+
+/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
+public final class BuildConfig {
+ public final static boolean DEBUG = Boolean.parseBoolean(null);
+}
\ No newline at end of file
diff --git a/example/android/app/src/main/gen/com/example/example/Manifest.java b/example/android/app/src/main/gen/com/example/example/Manifest.java
new file mode 100644
index 0000000..d17646d
--- /dev/null
+++ b/example/android/app/src/main/gen/com/example/example/Manifest.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.example.example;
+
+/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
+public final class Manifest {
+}
\ No newline at end of file
diff --git a/example/android/app/src/main/gen/com/example/example/R.java b/example/android/app/src/main/gen/com/example/example/R.java
new file mode 100644
index 0000000..015570b
--- /dev/null
+++ b/example/android/app/src/main/gen/com/example/example/R.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.example.example;
+
+/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
+public final class R {
+}
\ No newline at end of file
diff --git a/flutter_spinkit.iml b/flutter_spinkit.iml
index 70b4a9b..cea31c3 100644
--- a/flutter_spinkit.iml
+++ b/flutter_spinkit.iml
@@ -3,20 +3,15 @@
-
-
-
-
-
+
-
-
+
\ No newline at end of file
diff --git a/lib/src/double_bounce.dart b/lib/src/double_bounce.dart
index a4d2e62..deef4a0 100644
--- a/lib/src/double_bounce.dart
+++ b/lib/src/double_bounce.dart
@@ -1,21 +1,19 @@
+import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class SpinKitDoubleBounce extends StatefulWidget {
const SpinKitDoubleBounce({
Key key,
- this.color,
+ @required this.color,
this.size = 50.0,
- this.itemBuilder,
this.duration = const Duration(milliseconds: 2000),
this.controller,
- }) : assert(!(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
- 'You should specify either a itemBuilder or a color'),
+ }) : assert(color != null),
assert(size != null),
super(key: key);
final Color color;
final double size;
- final IndexedWidgetBuilder itemBuilder;
final Duration duration;
final AnimationController controller;
@@ -32,9 +30,9 @@ class _SpinKitDoubleBounceState extends State with SingleTi
super.initState();
_controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
- ..addListener(() => setState(() {}))
..repeat(reverse: true);
- _animation = Tween(begin: -1.0, end: 1.0).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
+ _animation =
+ Tween(begin: -1.0, end: 1.0).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
}
@override
@@ -46,18 +44,54 @@ class _SpinKitDoubleBounceState extends State with SingleTi
@override
Widget build(BuildContext context) {
return Center(
- child: Stack(
- children: List.generate(2, (i) {
- return Transform.scale(
- scale: (1.0 - i - _animation.value.abs()).abs(),
- child: SizedBox.fromSize(size: Size.square(widget.size), child: _itemBuilder(i)),
+ child: AnimatedBuilder(
+ animation: _animation,
+ builder: (context, _) {
+ return CustomPaint(
+ size: Size.square(widget.size),
+ painter: DoubleBouncePainter(
+ color: widget.color,
+ opacity: 0.6,
+ doubleBounceSize: _animation.value.abs() * widget.size,
+ ),
);
- }),
+ },
),
);
}
+}
+
+class DoubleBouncePainter extends CustomPainter {
+ DoubleBouncePainter({
+ @required this.doubleBounceSize,
+ @required double opacity,
+ @required Color color,
+ }) : _doubleBouncePaint = Paint()
+ ..color = color.withOpacity(opacity)
+ ..style = PaintingStyle.fill
+ ..isAntiAlias = true;
+
+ final double doubleBounceSize;
+ final Paint _doubleBouncePaint;
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final centerX = size.width / 2.0;
+ final centerY = size.height / 2.0;
+ canvas.drawCircle(
+ Offset(centerX, centerY),
+ doubleBounceSize / 2,
+ _doubleBouncePaint,
+ );
+ canvas.drawCircle(
+ Offset(centerX, centerY),
+ size.longestSide / 2 - (doubleBounceSize / 2),
+ _doubleBouncePaint,
+ );
+ }
- Widget _itemBuilder(int index) => widget.itemBuilder != null
- ? widget.itemBuilder(context, index)
- : DecoratedBox(decoration: BoxDecoration(shape: BoxShape.circle, color: widget.color.withOpacity(0.6)));
+ @override
+ bool shouldRepaint(DoubleBouncePainter oldDelegate) {
+ return oldDelegate.doubleBounceSize != doubleBounceSize;
+ }
}
diff --git a/lib/src/pulse.dart b/lib/src/pulse.dart
index 3750210..e53746b 100644
--- a/lib/src/pulse.dart
+++ b/lib/src/pulse.dart
@@ -1,21 +1,19 @@
+import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class SpinKitPulse extends StatefulWidget {
const SpinKitPulse({
Key key,
- this.color,
+ @required this.color,
this.size = 50.0,
- this.itemBuilder,
this.duration = const Duration(seconds: 1),
this.controller,
- }) : assert(!(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
- 'You should specify either a itemBuilder or a color'),
+ }) : assert(color != null),
assert(size != null),
super(key: key);
final Color color;
final double size;
- final IndexedWidgetBuilder itemBuilder;
final Duration duration;
final AnimationController controller;
@@ -23,7 +21,8 @@ class SpinKitPulse extends StatefulWidget {
_SpinKitPulseState createState() => _SpinKitPulseState();
}
-class _SpinKitPulseState extends State with SingleTickerProviderStateMixin {
+class _SpinKitPulseState extends State
+ with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _animation;
@@ -31,9 +30,10 @@ class _SpinKitPulseState extends State with SingleTickerProviderSt
void initState() {
super.initState();
- _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
- ..addListener(() => setState(() {}))
+ _controller = (widget.controller ??
+ AnimationController(vsync: this, duration: widget.duration))
..repeat();
+
_animation = CurveTween(curve: Curves.easeInOut).animate(_controller);
}
@@ -46,20 +46,48 @@ class _SpinKitPulseState extends State with SingleTickerProviderSt
@override
Widget build(BuildContext context) {
return Center(
- child: Opacity(
- opacity: 1.0 - _animation.value,
- child: Transform.scale(
- scale: _animation.value,
- child: SizedBox.fromSize(
+ child: AnimatedBuilder(
+ animation: _animation,
+ builder: (context, _) {
+ return CustomPaint(
size: Size.square(widget.size),
- child: _itemBuilder(0),
- ),
- ),
+ painter: PulsePainter(
+ color: widget.color,
+ opacity: 1.0 - _animation.value,
+ pulseSize: _animation.value * widget.size,
+ ),
+ );
+ },
),
);
}
-
- Widget _itemBuilder(int index) => widget.itemBuilder != null
- ? widget.itemBuilder(context, index)
- : DecoratedBox(decoration: BoxDecoration(shape: BoxShape.circle, color: widget.color));
}
+
+class PulsePainter extends CustomPainter {
+ PulsePainter({
+ @required this.pulseSize,
+ @required double opacity,
+ @required Color color,
+ }) : _pulsePaint = Paint()
+ ..color = color.withOpacity(opacity)
+ ..style = PaintingStyle.fill
+ ..isAntiAlias = true;
+
+
+
+ final double pulseSize;
+ final Paint _pulsePaint;
+
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final centerX = size.width / 2.0;
+ final centerY = size.height / 2.0;
+ canvas.drawCircle(Offset(centerX, centerY), pulseSize/2, _pulsePaint);
+ }
+
+ @override
+ bool shouldRepaint(PulsePainter oldDelegate) {
+ return oldDelegate.pulseSize != pulseSize;
+ }
+}
\ No newline at end of file
diff --git a/lib/src/pumping_heart.dart b/lib/src/pumping_heart.dart
index c85aa73..0ac1f71 100644
--- a/lib/src/pumping_heart.dart
+++ b/lib/src/pumping_heart.dart
@@ -1,24 +1,21 @@
import 'dart:math' as math show pow;
-import 'package:flutter/material.dart' show Icons;
+import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class SpinKitPumpingHeart extends StatefulWidget {
const SpinKitPumpingHeart({
Key key,
- this.color,
+ @required this.color,
this.size = 50.0,
- this.itemBuilder,
this.duration = const Duration(milliseconds: 2400),
this.controller,
- }) : assert(!(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
- 'You should specify either a itemBuilder or a color'),
+ }) : assert(color != null),
assert(size != null),
super(key: key);
final Color color;
final double size;
- final IndexedWidgetBuilder itemBuilder;
final Duration duration;
final AnimationController controller;
@@ -34,9 +31,10 @@ class _SpinKitPumpingHeartState extends State with SingleTi
void initState() {
super.initState();
- _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))..repeat();
- _animation = Tween(begin: 1.0, end: 1.25)
- .animate(CurvedAnimation(parent: _controller, curve: const Interval(0.0, 1.0, curve: SpinKitPumpCurve())));
+ _controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
+ ..repeat();
+ _animation = Tween(begin: 1.0, end: 1.25).animate(
+ CurvedAnimation(parent: _controller, curve: const Interval(0.0, 1.0, curve: SpinKitPumpCurve())));
}
@override
@@ -47,12 +45,66 @@ class _SpinKitPumpingHeartState extends State with SingleTi
@override
Widget build(BuildContext context) {
- return ScaleTransition(scale: _animation, child: _itemBuilder(0));
+ return ScaleTransition(
+ scale: _animation,
+ child: CustomPaint(
+ size: Size.square(widget.size),
+ painter: HeartPainter(
+ color: widget.color,
+ ),
+ ),
+ );
}
+}
+
+class HeartPainter extends CustomPainter {
+ HeartPainter({
+ @required Color color,
+ }) : _heartPaint = Paint()
+ ..color = color
+ ..style = PaintingStyle.fill
+ ..isAntiAlias = true;
+
+ final Paint _heartPaint;
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final double width = size.width;
+ final double height = size.height;
+
+ final Path heartPath = Path();
- Widget _itemBuilder(int index) => widget.itemBuilder != null
- ? widget.itemBuilder(context, index)
- : Icon(Icons.favorite, color: widget.color, size: widget.size);
+ //creating heart left half
+ heartPath.moveTo(0.5 * width, height * 0.15);
+ heartPath.cubicTo(
+ 0.2 * width,
+ height * -0.2,
+ -0.2 * width,
+ height * 0.3,
+ 0.1 * width,
+ height * 0.6,
+ );
+ heartPath.lineTo(0.5 * width, height);
+
+ //creating heart left half
+ heartPath.moveTo(0.5 * width, height * 0.15);
+ heartPath.cubicTo(
+ 0.8 * width,
+ height * -0.2,
+ 1.2 * width,
+ height * 0.3,
+ 0.9 * width,
+ height * 0.6,
+ );
+ heartPath.lineTo(0.5 * width, height);
+
+ canvas.drawPath(heartPath, _heartPaint);
+ }
+
+ @override
+ bool shouldRepaint(HeartPainter oldDelegate) {
+ return oldDelegate._heartPaint != _heartPaint;
+ }
}
class SpinKitPumpCurve extends Curve {
diff --git a/lib/src/square_circle.dart b/lib/src/square_circle.dart
index 1e28469..188efaa 100644
--- a/lib/src/square_circle.dart
+++ b/lib/src/square_circle.dart
@@ -5,19 +5,16 @@ import 'package:flutter/widgets.dart';
class SpinKitSquareCircle extends StatefulWidget {
const SpinKitSquareCircle({
Key key,
- this.color,
+ @required this.color,
this.size = 50.0,
- this.itemBuilder,
this.duration = const Duration(milliseconds: 500),
this.controller,
- }) : assert(!(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
- 'You should specify either a itemBuilder or a color'),
+ }) : assert(color != null),
assert(size != null),
super(key: key);
final Color color;
final double size;
- final IndexedWidgetBuilder itemBuilder;
final Duration duration;
final AnimationController controller;
@@ -35,7 +32,6 @@ class _SpinKitSquareCircleState extends State with SingleTi
super.initState();
controller = (widget.controller ?? AnimationController(vsync: this, duration: widget.duration))
- ..addListener(() => setState(() {}))
..repeat(reverse: true);
final animation = CurvedAnimation(parent: controller, curve: Curves.easeInOutCubic);
animationCurve = Tween(begin: 1.0, end: 0.0).animate(animation);
@@ -50,25 +46,68 @@ class _SpinKitSquareCircleState extends State with SingleTi
@override
Widget build(BuildContext context) {
- final sizeValue = widget.size * animationSize.value;
- return Center(
- child: Transform(
- transform: Matrix4.identity()..rotateZ(animationCurve.value * math.pi),
- alignment: FractionalOffset.center,
- child: SizedBox.fromSize(
- size: Size.square(sizeValue),
- child: _itembuilder(0, 0.5 * sizeValue * animationCurve.value),
- ),
+ return AnimatedBuilder(
+ animation: controller,
+ builder: (context, _) {
+ final sizeValue = widget.size * animationSize.value;
+ return Center(
+ child: CustomPaint(
+ size: Size.square(sizeValue),
+ painter: SquareCirclePainter(
+ rotate: animationCurve.value * math.pi,
+ borderRadius: 0.5 * sizeValue * animationCurve.value,
+ color: widget.color,
+ ),
+ ),
+ );
+ });
+ }
+}
+
+class SquareCirclePainter extends CustomPainter {
+ SquareCirclePainter({
+ @required this.borderRadius,
+ @required this.rotate,
+ @required Color color,
+ }) : _squareCirclePaint = Paint()
+ ..style = PaintingStyle.fill
+ ..color = color
+ ..isAntiAlias = true;
+
+ final double borderRadius;
+ final double rotate;
+ final Paint _squareCirclePaint;
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final rRect = RRect.fromRectAndRadius(
+ Rect.fromLTWH(
+ 0,
+ 0,
+ size.width,
+ size.height,
),
+ Radius.circular(borderRadius),
);
+
+ //circle rotation
+ final double r = math.sqrt(size.width * size.width + size.height * size.height) / 2;
+ final alpha = math.atan(size.height / size.width);
+ final beta = alpha + rotate;
+ final shiftY = r * math.sin(beta);
+ final shiftX = r * math.cos(beta);
+ final translateX = size.width / 2 - shiftX;
+ final translateY = size.height / 2 - shiftY;
+
+ canvas.translate(translateX, translateY);
+
+ canvas.rotate(rotate);
+
+ canvas.drawRRect(rRect, _squareCirclePaint);
}
- Widget _itembuilder(int index, double curveValue) => widget.itemBuilder != null
- ? widget.itemBuilder(context, index)
- : DecoratedBox(
- decoration: BoxDecoration(
- color: widget.color,
- borderRadius: BorderRadius.all(Radius.circular(curveValue)),
- ),
- );
+ @override
+ bool shouldRepaint(SquareCirclePainter oldDelegate) {
+ return oldDelegate.borderRadius != borderRadius;
+ }
}
diff --git a/lib/src/wave.dart b/lib/src/wave.dart
index ff02c79..a2bd450 100644
--- a/lib/src/wave.dart
+++ b/lib/src/wave.dart
@@ -13,7 +13,9 @@ class SpinKitWave extends StatefulWidget {
this.itemCount = 5,
this.duration = const Duration(milliseconds: 1200),
this.controller,
- }) : assert(!(itemBuilder is IndexedWidgetBuilder && color is Color) && !(itemBuilder == null && color == null),
+ }) : assert(
+ !(itemBuilder is IndexedWidgetBuilder && color is Color) &&
+ !(itemBuilder == null && color == null),
'You should specify either a itemBuilder or a color'),
assert(itemCount != null && itemCount >= 2, 'itemCount Cant be less then 2 '),
assert(type != null),
@@ -59,7 +61,8 @@ class _SpinKitWaveState extends State with SingleTickerProviderStat
children: List.generate(_bars.length, (i) {
return ScaleYWidget(
scaleY: DelayTween(begin: .4, end: 1.0, delay: _bars[i]).animate(_controller),
- child: SizedBox.fromSize(size: Size(widget.size / widget.itemCount, widget.size), child: _itemBuilder(i)),
+ child: SizedBox.fromSize(
+ size: Size(widget.size / widget.itemCount, widget.size), child: _itemBuilder(i)),
);
}),
),