Skip to content

Commit

Permalink
Revised _textKey to not be a global variable. Resolves #129. (#130)
Browse files Browse the repository at this point in the history
* Revised _textKey to not be a global variable. Resolves #129.
* Reformatted code and moved default values from the _State class to the StatefulWidget.
* Replaced Duration constants with seconds instead of milliseconds to be consistent with documentation.
  • Loading branch information
awhitford committed Oct 23, 2020
1 parent 26a81ef commit fce7109
Showing 1 changed file with 80 additions and 81 deletions.
161 changes: 80 additions & 81 deletions lib/src/text_liquid_fill.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'package:flutter/material.dart';
import 'dart:math';

GlobalKey _textKey;
import 'package:flutter/material.dart';

class TextLiquidFill extends StatefulWidget {
/// Gives [TextStyle] to the text string.
///
/// By default it is `TextStyle(fontSize: 140, fontWeight: FontWeight.bold)`
final TextStyle textStyle;

/// Gives [TextAlign] to the text string.
///
/// By default it is [TextAlign.left].
final TextAlign textAlign;

/// Specifies the duration the text should fill with liquid.
Expand Down Expand Up @@ -43,66 +45,57 @@ class TextLiquidFill extends StatefulWidget {
/// By default it is set to blueAccent color
final Color waveColor;

TextLiquidFill(
{Key key,
@required this.text,
this.textStyle,
this.textAlign,
this.loadDuration,
this.waveDuration,
this.boxHeight,
this.boxWidth,
this.boxBackgroundColor,
this.waveColor})
: super(key: key);
TextLiquidFill({
Key key,
@required this.text,
this.textStyle =
const TextStyle(fontSize: 140, fontWeight: FontWeight.bold),
this.textAlign = TextAlign.left,
this.loadDuration = const Duration(seconds: 6),
this.waveDuration = const Duration(seconds: 2),
this.boxHeight = 250,
this.boxWidth = 400,
this.boxBackgroundColor = Colors.black,
this.waveColor = Colors.blueAccent,
}) : assert(null != text),
assert(null != textStyle),
assert(null != textAlign),
assert(null != loadDuration),
assert(null != waveDuration),
assert(null != boxHeight),
assert(null != boxWidth),
assert(null != boxBackgroundColor),
assert(null != waveColor),
super(key: key);

@override
_TextLiquidFillState createState() => _TextLiquidFillState();
}

class _TextLiquidFillState extends State<TextLiquidFill>
with TickerProviderStateMixin {
final _textKey = GlobalKey();

AnimationController _waveController, _loadController;
Duration _waveDuration, _loadDuration;

Animation _loadValue;

double _boxHeight, _boxWidth;

Color _boxBackgroundColor, _waveColor;

TextStyle _textStyle;

TextAlign _textAlign;

@override
void initState() {
super.initState();

_textKey = GlobalKey();

_boxHeight = widget.boxHeight ?? 250;

_boxWidth = widget.boxWidth ?? 400;

_waveDuration = widget.waveDuration ?? const Duration(milliseconds: 2000);

_loadDuration = widget.loadDuration ?? const Duration(milliseconds: 6000);

_waveController = AnimationController(vsync: this, duration: _waveDuration);
_waveController = AnimationController(
vsync: this,
duration: widget.waveDuration,
);

_loadController = AnimationController(vsync: this, duration: _loadDuration);
_loadController = AnimationController(
vsync: this,
duration: widget.loadDuration,
);

_loadValue = Tween<double>(begin: 0.0, end: 100.0).animate(_loadController);

_boxBackgroundColor = widget.boxBackgroundColor ?? Colors.black;
_waveColor = widget.waveColor ?? Colors.blueAccent;

_textStyle = widget.textStyle ??
TextStyle(fontSize: 140, fontWeight: FontWeight.bold);

_textAlign = widget.textAlign ?? TextAlign.left;

_waveController.repeat();
_loadController.forward();
}
Expand All @@ -121,37 +114,40 @@ class _TextLiquidFillState extends State<TextLiquidFill>
return Stack(
children: <Widget>[
SizedBox(
height: _boxHeight,
width: _boxWidth ?? MediaQuery.of(context).size.width,
height: widget.boxHeight,
width: widget.boxWidth,
child: AnimatedBuilder(
animation: _waveController,
builder: (BuildContext context, Widget child) {
return CustomPaint(
painter: WavePainter(
waveAnimation: _waveController,
percentValue: _loadValue.value,
boxHeight: _boxHeight,
waveColor: _waveColor),
textKey: _textKey,
waveAnimation: _waveController,
percentValue: _loadValue.value,
boxHeight: widget.boxHeight,
waveColor: widget.waveColor,
),
);
},
),
),
SizedBox(
height: _boxHeight,
width: _boxWidth ?? MediaQuery.of(context).size.width,
height: widget.boxHeight,
width: widget.boxWidth,
child: ShaderMask(
blendMode: BlendMode.srcOut,
shaderCallback: (bounds) =>
LinearGradient(colors: [_boxBackgroundColor], stops: [0.0])
.createShader(bounds),
shaderCallback: (bounds) => LinearGradient(
colors: [widget.boxBackgroundColor],
stops: [0.0],
).createShader(bounds),
child: Container(
color: Colors.transparent,
child: Center(
child: Text(
widget.text,
key: _textKey,
style: _textStyle,
textAlign: _textAlign,
style: widget.textStyle,
textAlign: widget.textAlign,
),
),
),
Expand All @@ -163,41 +159,44 @@ class _TextLiquidFillState extends State<TextLiquidFill>
}

class WavePainter extends CustomPainter {
Animation<double> waveAnimation;
double percentValue;
double boxHeight;
Color waveColor;
final _pi2 = 2 * pi;
final GlobalKey textKey;
final Animation<double> waveAnimation;
final double percentValue;
final double boxHeight;
final Color waveColor;

WavePainter(
{this.waveAnimation, this.percentValue, this.boxHeight, this.waveColor});
WavePainter({
@required this.textKey,
this.waveAnimation,
this.percentValue,
this.boxHeight,
this.waveColor,
});

@override
void paint(Canvas canvas, Size size) {
double width = (size.width != null) ? size.width : 200;
double height = (size.height != null) ? size.height : 200;

Paint wavePaint = Paint()..color = waveColor;

RenderBox textBox = _textKey.currentContext.findRenderObject();

double _textHeight = textBox.size.height;

double _percent = percentValue / 100.0;
double _baseHeight =
(boxHeight / 2) + (_textHeight / 2) - (_percent * _textHeight);

Path path = Path();
path.moveTo(0.0, _baseHeight);
final RenderBox textBox = textKey.currentContext.findRenderObject();
final textHeight = textBox.size.height;
final percent = percentValue / 100.0;
final baseHeight =
(boxHeight / 2) + (textHeight / 2) - (percent * textHeight);

final width = size.width ?? 200;
final height = size.height ?? 200;
final path = Path();
path.moveTo(0.0, baseHeight);
for (double i = 0.0; i < width; i++) {
path.lineTo(
i,
_baseHeight +
sin((i / width * 2 * pi) + (waveAnimation.value * 2 * pi)) * 8);
i,
baseHeight + sin((i / width * _pi2) + (waveAnimation.value * _pi2)) * 8,
);
}

path.lineTo(width, height);
path.lineTo(0.0, height);
path.close();
final wavePaint = Paint()..color = waveColor;
canvas.drawPath(path, wavePaint);
}

Expand Down

0 comments on commit fce7109

Please sign in to comment.