Flutter Vignette —Liquid Cards
Flutter Vignette — Liquid Cards
How to master the Liquid Cards Vignette (by gskinner team)…Hmmm
All in one Flutter resource: https://flatteredwithflutter.com/liquid-cards-vignette/
Flutter Vignette — Liquid Cards
How to master the Liquid Cards Vignette (by gskinner team)…Hmmm
All in one Flutter resource: https://flatteredwithflutter.com/liquid-cards-vignette/
Other Vignettes :
For Flutter Interact ’19, Google challenged gskinner to showcase the Flutter framework’s capabilities to build beautiful apps.
What are we covering today…?
Liquid Cards: This demo aims to utilize the Flutter’s list of widgets, specially AnimtedContainer, and finally Flutter’s Canvas to simulate a liquid effect.

This tutorial is divided into 3 steps :
Data part is static and is taken from the original source code….
We replicate the data for drinks (static data)….

Body is basically a Stack of widgets (top -> My rewards, bottom -> list of cards/drinks)
Top section (My rewards):
Bottom section (List of Cards)
Things to Note :

var lst = [1,2,3,4,5];
var res = lst.reduce((i, j) => i + j);
print('res is ${res}'); // res is 15
In this step, we have kept the card closed (as per vignette). On the opening or closing of each card, animation gets triggered……
Also, there is a border (rounded) for each card….
Things to Note :
Each card is wrapped inside AnimatedContainer. We detect whether the card is clicked and then animate the height of the card…

const ElasticOutCurve([this.period = 0.4]);Meaning we can even alter the curves :)

In case you want your widget to be bordered exactly,

We integrate the liquid effect animation….
Things to Note :
AnimatedOpacity(
opacity: widget.isOpen ? 1 : 0,
duration: Duration(milliseconds: 500),
child: _buildLiquidBackground(_maxFillLevel, fillLevel),
)return Stack(
fit: StackFit.expand,
children: <Widget>[
Transform.translate(
offset: Offset(
0,
DrinkListCard.nominalHeightOpen * 1.2 -
DrinkListCard.nominalHeightOpen *
_fillTween.value *
_maxFillLevel *
1.2,
),
child: CustomPaint(
painter: LiquidPainter(
fillLevel,
_liquidSim1,
_liquidSim2,
waveHeight: 100,
),
),
),
],
);_buildLiquidBackground(code above) is made up of
We need to start the wave from bottom to top, meaning from one offset to another..Hail, this widget…:)
Offset : Takes 2 params (dx, dy) ….dx = 0.0
dy -> depends on the points left (as per card) and the current animation value..
We override the paint method of this painter, to include 2 waves…
@override
void paint(Canvas canvas, Size size) {
_drawLiquidSim(
simulation1,
canvas,
size,
0,
Color(0xffC48D3B).withOpacity(.4),
);
_drawLiquidSim(
simulation2,
canvas,
size,
5,
Color(0xff9D7B32).withOpacity(.4),
);
}// DEF. OF _drawLiquidSimvoid _drawLiquidSim(
LiquidSimulation simulation,
Canvas canvas,
Size size,
double offsetY,
Color color
)In _drawLiquidSim, we create a path from left side of the card to the right. Before rendering the path, we modify it in the form of quadraticBezierCurve
For each, quadraticBezierTo, we require control points
path.quadraticBezierTo(ctrlPt.dx, ctrlPt.dy, endPt.dx, endPt.dy);Hence, we created a custom class, LiquidSimulation and outsource the control points calculation inside it….
In this class, we
var animSequence = TweenSequence([
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0, end: 0),
weight: 10.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0, end: height).chain(
CurveTween(curve: Curves.linear),
),
weight: 10.0,
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: height, end: 0).chain(
CurveTween(curve: _ease),
),
weight: 60.0,
)
]).animate(controller)Introducing chaining of animations….
Using TweenSequenceItem, we direct our animation’s curve to stay the same for the desired weight (begin and end)
Tween<double>(begin: 0, end: height)This, in turn, creates a nonlinear progression of animations….
Articles related to Flutter Desktop:
