Line data Source code
1 : import 'dart:math';
2 :
3 : import 'package:flutter/material.dart';
4 : import 'package:liquid_swipe/Helpers/Helpers.dart';
5 :
6 : ///Liquid Type PathClipper
7 : class WaveLayer extends CustomClipper<Path> {
8 : double revealPercent;
9 : double verReveal;
10 : late double waveCenterY;
11 : late double waveHorRadius;
12 : late double waveVertRadius;
13 : late double sideWidth;
14 : Size iconSize;
15 : SlideDirection? slideDirection;
16 : bool enableSideReveal;
17 :
18 2 : WaveLayer({
19 : required this.revealPercent,
20 : required this.slideDirection,
21 : required this.iconSize,
22 : required this.verReveal,
23 : required this.enableSideReveal,
24 : });
25 :
26 2 : @override
27 : getClip(Size size) {
28 2 : Path path = Path();
29 4 : sideWidth = sidewidth(size);
30 4 : waveVertRadius = waveVertRadiusF(size);
31 :
32 8 : waveCenterY = size.height * verReveal;
33 6 : waveHorRadius = slideDirection == SlideDirection.leftToRight
34 0 : ? waveHorRadiusFBack(size)
35 2 : : waveHorRadiusF(size);
36 :
37 6 : var maskWidth = size.width - sideWidth;
38 6 : path.moveTo(maskWidth - sideWidth, 0);
39 2 : path.lineTo(0, 0);
40 4 : path.lineTo(0, size.height);
41 4 : path.lineTo(maskWidth, size.height);
42 6 : double curveStartY = waveCenterY + waveVertRadius;
43 :
44 2 : path.lineTo(maskWidth, curveStartY);
45 :
46 2 : path.cubicTo(
47 : maskWidth,
48 6 : curveStartY - waveVertRadius * 0.1346194756,
49 6 : maskWidth - waveHorRadius * 0.05341339583,
50 6 : curveStartY - waveVertRadius * 0.2412779634,
51 6 : maskWidth - waveHorRadius * 0.1561501458,
52 6 : curveStartY - waveVertRadius * 0.3322374268,
53 : );
54 :
55 2 : path.cubicTo(
56 6 : maskWidth - waveHorRadius * 0.2361659167,
57 6 : curveStartY - waveVertRadius * 0.4030805244,
58 6 : maskWidth - waveHorRadius * 0.3305285625,
59 6 : curveStartY - waveVertRadius * 0.4561193293,
60 6 : maskWidth - waveHorRadius * 0.5012484792,
61 6 : curveStartY - waveVertRadius * 0.5350576951,
62 : );
63 :
64 2 : path.cubicTo(
65 6 : maskWidth - waveHorRadius * 0.515878125,
66 6 : curveStartY - waveVertRadius * 0.5418222317,
67 6 : maskWidth - waveHorRadius * 0.5664134792,
68 6 : curveStartY - waveVertRadius * 0.5650349878,
69 6 : maskWidth - waveHorRadius * 0.574934875,
70 6 : curveStartY - waveVertRadius * 0.5689655122,
71 : );
72 :
73 2 : path.cubicTo(
74 6 : maskWidth - waveHorRadius * 0.7283715208,
75 6 : curveStartY - waveVertRadius * 0.6397387195,
76 6 : maskWidth - waveHorRadius * 0.8086618958,
77 6 : curveStartY - waveVertRadius * 0.6833456585,
78 6 : maskWidth - waveHorRadius * 0.8774032292,
79 6 : curveStartY - waveVertRadius * 0.7399037439,
80 : );
81 :
82 2 : path.cubicTo(
83 6 : maskWidth - waveHorRadius * 0.9653464583,
84 6 : curveStartY - waveVertRadius * 0.8122605122,
85 4 : maskWidth - waveHorRadius,
86 6 : curveStartY - waveVertRadius * 0.8936183659,
87 4 : maskWidth - waveHorRadius,
88 4 : curveStartY - waveVertRadius,
89 : );
90 :
91 2 : path.cubicTo(
92 4 : maskWidth - waveHorRadius,
93 6 : curveStartY - waveVertRadius * 1.100142878,
94 6 : maskWidth - waveHorRadius * 0.9595746667,
95 6 : curveStartY - waveVertRadius * 1.1887991951,
96 6 : maskWidth - waveHorRadius * 0.8608411667,
97 6 : curveStartY - waveVertRadius * 1.270484439,
98 : );
99 :
100 2 : path.cubicTo(
101 6 : maskWidth - waveHorRadius * 0.7852123333,
102 6 : curveStartY - waveVertRadius * 1.3330544756,
103 6 : maskWidth - waveHorRadius * 0.703382125,
104 6 : curveStartY - waveVertRadius * 1.3795848049,
105 6 : maskWidth - waveHorRadius * 0.5291125625,
106 6 : curveStartY - waveVertRadius * 1.4665102805,
107 : );
108 :
109 2 : path.cubicTo(
110 6 : maskWidth - waveHorRadius * 0.5241858333,
111 6 : curveStartY - waveVertRadius * 1.4689677195,
112 6 : maskWidth - waveHorRadius * 0.505739125,
113 6 : curveStartY - waveVertRadius * 1.4781625854,
114 6 : maskWidth - waveHorRadius * 0.5015305417,
115 6 : curveStartY - waveVertRadius * 1.4802616098,
116 : );
117 :
118 2 : path.cubicTo(
119 6 : maskWidth - waveHorRadius * 0.3187486042,
120 6 : curveStartY - waveVertRadius * 1.5714239024,
121 6 : maskWidth - waveHorRadius * 0.2332057083,
122 6 : curveStartY - waveVertRadius * 1.6204116463,
123 6 : maskWidth - waveHorRadius * 0.1541165417,
124 6 : curveStartY - waveVertRadius * 1.687403,
125 : );
126 :
127 2 : path.cubicTo(
128 6 : maskWidth - waveHorRadius * 0.0509933125,
129 6 : curveStartY - waveVertRadius * 1.774752061,
130 : maskWidth,
131 6 : curveStartY - waveVertRadius * 1.8709256829,
132 : maskWidth,
133 6 : curveStartY - waveVertRadius * 2,
134 : );
135 :
136 2 : path.lineTo(maskWidth, 0);
137 2 : path.close();
138 :
139 : return path;
140 : }
141 :
142 2 : double sidewidth(Size size) {
143 : var p1 = 0.2;
144 : var p2 = 0.8;
145 :
146 4 : if (revealPercent <= p1) {
147 2 : return enableSideReveal ? 15.0 : 0;
148 : }
149 :
150 2 : if (revealPercent >= p2) {
151 1 : return size.width;
152 : }
153 :
154 0 : return 15 + (size.width - 15.0) * (revealPercent - p1) / (p2 - p1);
155 : }
156 :
157 2 : @override
158 : bool shouldReclip(CustomClipper oldClipper) {
159 : return true;
160 : }
161 :
162 2 : double waveVertRadiusF(Size size) {
163 : var p1 = 0.4;
164 :
165 4 : if (revealPercent <= 0) {
166 4 : return enableSideReveal ? iconSize.height : 0;
167 : }
168 :
169 2 : if (revealPercent >= p1) {
170 2 : return size.height * 0.9;
171 : }
172 :
173 0 : return iconSize.height +
174 0 : ((size.height * 0.9) - iconSize.height) * revealPercent / p1;
175 : }
176 :
177 2 : double waveHorRadiusF(Size size) {
178 4 : if (revealPercent <= 0) {
179 4 : return iconSize.width;
180 : }
181 :
182 2 : if (revealPercent >= 1) {
183 : return 0;
184 : }
185 :
186 : var p1 = 0.4;
187 0 : if (revealPercent <= p1) {
188 0 : return iconSize.width +
189 0 : revealPercent / p1 * ((size.width * 0.8) - iconSize.width);
190 : }
191 :
192 0 : var t = (revealPercent - p1) / (1.0 - p1);
193 0 : var A = size.width * 0.9;
194 : var r = 40;
195 : var m = 9.8;
196 0 : var beta = r / (2 * m);
197 : var k = 50;
198 0 : var omega0 = k / m;
199 0 : var omega = pow(-pow(beta, 2) + pow(omega0, 2), 0.5);
200 :
201 0 : return A * exp(-beta * t) * cos(omega * t);
202 : }
203 :
204 1 : double waveHorRadiusFBack(Size size) {
205 2 : if (revealPercent <= 0) {
206 2 : return iconSize.width;
207 : }
208 :
209 0 : if (revealPercent >= 1) {
210 : return 0;
211 : }
212 :
213 : var p1 = 0.4;
214 0 : if (revealPercent <= p1) {
215 0 : return iconSize.width + revealPercent / p1 * iconSize.width;
216 : }
217 :
218 0 : var t = (revealPercent - p1) / (1.0 - p1);
219 0 : var A = iconSize.width + 8;
220 : var r = 40;
221 : var m = 9.8;
222 0 : var beta = r / (2 * m);
223 : var k = 50;
224 0 : var omega0 = k / m;
225 0 : var omega = pow(-pow(beta, 2) + pow(omega0, 2), 0.5);
226 :
227 0 : return A * exp(-beta * t) * cos(omega * t);
228 : }
229 : }
|