Skip to content

Commit de71ddc

Browse files
committed
A nice folder open animation with shining ligntning added without any addd physics lib
1 parent 9cc890d commit de71ddc

File tree

5 files changed

+390
-67
lines changed

5 files changed

+390
-67
lines changed

assets/images/folder_backcover.png

4.3 KB
Loading

assets/images/folder_frontcover.png

116 KB
Loading

lib/folder_shape/gradient_shadow.dart

+272
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
import 'package:flutter/material.dart';
2+
3+
class FolderBackCoverGradientPainter extends CustomPainter {
4+
final Animation<double> animation;
5+
FolderBackCoverGradientPainter(this.animation) : super(repaint: animation);
6+
@override
7+
void paint(Canvas canvas, Size size) {
8+
Path path = Path();
9+
10+
path.lineTo(0, size.height * 0.08);
11+
path.cubicTo(
12+
0, size.height * 0.03, size.width * 0.02, 0, size.width * 0.06, 0);
13+
path.cubicTo(
14+
size.width * 0.06, 0, size.width * 0.17, 0, size.width * 0.17, 0);
15+
path.cubicTo(
16+
size.width * 0.17, 0, size.width * 0.29, 0, size.width * 0.29, 0);
17+
path.cubicTo(size.width * 0.31, 0, size.width / 3, size.height * 0.01,
18+
size.width * 0.34, size.height * 0.03);
19+
path.cubicTo(size.width * 0.34, size.height * 0.03, size.width * 0.4,
20+
size.height * 0.17, size.width * 0.4, size.height * 0.17);
21+
path.cubicTo(size.width * 0.41, size.height * 0.19, size.width * 0.43,
22+
size.height / 5, size.width * 0.45, size.height / 5);
23+
path.cubicTo(size.width * 0.45, size.height / 5, size.width * 0.57,
24+
size.height / 5, size.width * 0.57, size.height / 5);
25+
path.cubicTo(size.width * 0.57, size.height / 5, size.width * 0.75,
26+
size.height / 5, size.width * 0.75, size.height / 5);
27+
path.cubicTo(size.width * 0.75, size.height / 5, size.width * 0.94,
28+
size.height / 5, size.width * 0.94, size.height / 5);
29+
path.cubicTo(size.width * 0.98, size.height / 5, size.width,
30+
size.height * 0.24, size.width, size.height * 0.28);
31+
path.cubicTo(size.width, size.height * 0.28, size.width, size.height * 0.92,
32+
size.width, size.height * 0.92);
33+
path.cubicTo(size.width, size.height * 0.97, size.width * 0.98, size.height,
34+
size.width * 0.94, size.height);
35+
path.cubicTo(size.width * 0.94, size.height, size.width * 0.06, size.height,
36+
size.width * 0.06, size.height);
37+
path.cubicTo(size.width * 0.02, size.height, 0, size.height * 0.97, 0,
38+
size.height * 0.92);
39+
path.cubicTo(
40+
0, size.height * 0.92, 0, size.height * 0.6, 0, size.height * 0.6);
41+
path.cubicTo(
42+
0, size.height * 0.6, 0, size.height * 0.41, 0, size.height * 0.41);
43+
path.cubicTo(0, size.height * 0.41, 0, size.height / 5, 0, size.height / 5);
44+
path.cubicTo(
45+
0, size.height / 5, 0, size.height * 0.08, 0, size.height * 0.08);
46+
path.cubicTo(
47+
0, size.height * 0.08, 0, size.height * 0.08, 0, size.height * 0.08);
48+
49+
final gradient = LinearGradient(
50+
begin: Alignment.topLeft,
51+
end: Alignment(-0.8, 1),
52+
stops: [0.0, 0.4 + 0.4 * animation.value], //from .4 to .8
53+
colors: [
54+
Colors.transparent,
55+
Colors.black.withOpacity(.7),
56+
],
57+
);
58+
59+
Paint paint = Paint()..shader = gradient.createShader(path.getBounds());
60+
canvas.drawPath(path, paint);
61+
}
62+
63+
@override
64+
bool shouldRepaint(CustomPainter oldDelegate) {
65+
return true;
66+
}
67+
}
68+
69+
class SVGPathPainter extends CustomPainter {
70+
@override
71+
void paint(Canvas canvas, Size size) {
72+
final Paint paint = Paint()
73+
..color = Colors.black
74+
..style = PaintingStyle.fill
75+
..strokeWidth = 1;
76+
77+
final Path path = Path();
78+
79+
// Normalize coordinates
80+
final double scaleX = size.width / 1080;
81+
final double scaleY = size.height / 1080;
82+
final double scale = scaleX < scaleY ? scaleX : scaleY;
83+
84+
// Transform and scale the canvas
85+
canvas.translate(size.width * .1, size.height * .1);
86+
canvas.scale(scale * 12.31);
87+
88+
// Draw the path
89+
path.moveTo(0, 10.6616);
90+
path.cubicTo(3.90088, 12.9416, 8.95617, 15.8621, 12.8524, 18.1541);
91+
path.cubicTo(17.5784, 20.9341, 22.7708, 24.0116, 27.605, 26.8484);
92+
path.cubicTo(27.5755, 26.6435, 27.5704, 26.6075, 27.5498, 26.4642);
93+
path.cubicTo(27.18, 23.8889, 26.8101, 21.3137, 26.4403, 18.7384);
94+
path.cubicTo(26.4094, 18.5237, 26.3836, 18.3437, 26.3577, 18.1637);
95+
path.cubicTo(33.1158, 23.5418, 40.6326, 29.5263, 47.3906, 34.9044);
96+
path.cubicTo(47.2732, 34.9845, 47.508, 34.8243, 47.3906, 34.9044);
97+
path.cubicTo(47.0196, 32.3213, 46.5572, 28.6123, 46.1862, 26.0292);
98+
path.cubicTo(57.4306, 36.1862, 71.4346, 48.7877, 82.679, 58.9447);
99+
path.cubicTo(82.7455, 58.8168, 82.6125, 59.0727, 82.679, 58.9447);
100+
path.cubicTo(73.6361, 52.9921, 61.7472, 45.1035, 52.7043, 39.1509);
101+
path.cubicTo(52.7233, 39.2828, 52.7491, 39.4628, 52.7717, 39.6199);
102+
path.cubicTo(53.1268, 42.0927, 53.482, 44.5655, 53.8371, 47.0384);
103+
path.cubicTo(53.8607, 47.2031, 53.8933, 47.4299, 53.9116, 47.5571);
104+
path.cubicTo(47.5775, 42.5648, 40.5147, 37.0975, 34.1806, 32.1052);
105+
path.cubicTo(34.2772, 32.0467, 34.084, 32.1637, 34.1806, 32.1052);
106+
path.cubicTo(34.5829, 34.9068, 35.1483, 38.844, 35.5507, 41.6456);
107+
path.cubicTo(35.6424, 41.5881, 35.4589, 41.7032, 35.5507, 41.6456);
108+
path.cubicTo(35.1997, 41.4099, 34.4457, 40.6258, 34.1216, 40.345);
109+
path.cubicTo(26.5458, 33.783, 18.9734, 27.2155, 11.4052, 20.6408);
110+
path.cubicTo(7.9682, 17.655, 3.44476, 13.774, 0, 10.6616);
111+
path.close();
112+
113+
canvas.drawPath(path, paint);
114+
}
115+
116+
@override
117+
bool shouldRepaint(CustomPainter oldDelegate) => false;
118+
}
119+
120+
class LightningClipper extends CustomClipper<Path> {
121+
@override
122+
Path getClip(Size size) {
123+
final path = Path();
124+
125+
// Calculate scale factors to fit the path within the given size
126+
const double originalWidth =
127+
82.679; // Approximate width of the original path
128+
const double originalHeight =
129+
48.2831; // Approximate height of the original path
130+
final double scaleX = size.width / originalWidth;
131+
final double scaleY = size.height / originalHeight;
132+
final double scale = (scaleX < scaleY ? scaleX : scaleY) * .6;
133+
134+
// Calculate the scaled width and height of the path
135+
final double scaledWidth = originalWidth * scale;
136+
final double scaledHeight = originalHeight * scale;
137+
138+
// Calculate the offset to center the path
139+
final double offsetX = (size.width - scaledWidth) / 2;
140+
final double offsetY = (size.height - scaledHeight) / 2;
141+
142+
// Apply scaling transform
143+
final Matrix4 matrix = Matrix4.identity()
144+
..scale(scale, scale)
145+
..translate(offsetX / scale, offsetY / scale);
146+
147+
path.moveTo(0, 10.6616);
148+
path.cubicTo(3.90088, 12.9416, 8.95617, 15.8621, 12.8524, 18.1541);
149+
path.cubicTo(17.5784, 20.9341, 22.7708, 24.0116, 27.605, 26.8484);
150+
path.cubicTo(27.5755, 26.6435, 27.5704, 26.6075, 27.5498, 26.4642);
151+
path.cubicTo(27.18, 23.8889, 26.8101, 21.3137, 26.4403, 18.7384);
152+
path.cubicTo(26.4094, 18.5237, 26.3836, 18.3437, 26.3577, 18.1637);
153+
path.cubicTo(33.1158, 23.5418, 40.6326, 29.5263, 47.3906, 34.9044);
154+
path.cubicTo(47.2732, 34.9845, 47.508, 34.8243, 47.3906, 34.9044);
155+
path.cubicTo(47.0196, 32.3213, 46.5572, 28.6123, 46.1862, 26.0292);
156+
path.cubicTo(57.4306, 36.1862, 71.4346, 48.7877, 82.679, 58.9447);
157+
path.cubicTo(82.7455, 58.8168, 82.6125, 59.0727, 82.679, 58.9447);
158+
path.cubicTo(73.6361, 52.9921, 61.7472, 45.1035, 52.7043, 39.1509);
159+
path.cubicTo(52.7233, 39.2828, 52.7491, 39.4628, 52.7717, 39.6199);
160+
path.cubicTo(53.1268, 42.0927, 53.482, 44.5655, 53.8371, 47.0384);
161+
path.cubicTo(53.8607, 47.2031, 53.8933, 47.4299, 53.9116, 47.5571);
162+
path.cubicTo(47.5775, 42.5648, 40.5147, 37.0975, 34.1806, 32.1052);
163+
path.cubicTo(34.2772, 32.0467, 34.084, 32.1637, 34.1806, 32.1052);
164+
path.cubicTo(34.5829, 34.9068, 35.1483, 38.844, 35.5507, 41.6456);
165+
path.cubicTo(35.6424, 41.5881, 35.4589, 41.7032, 35.5507, 41.6456);
166+
path.cubicTo(35.1997, 41.4099, 34.4457, 40.6258, 34.1216, 40.345);
167+
path.cubicTo(26.5458, 33.783, 18.9734, 27.2155, 11.4052, 20.6408);
168+
path.cubicTo(7.9682, 17.655, 3.44476, 13.774, 0, 10.6616);
169+
path.close();
170+
171+
// Apply the scaling transform to the path
172+
return path.transform(matrix.storage);
173+
}
174+
175+
@override
176+
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
177+
}
178+
179+
class BigCirclePainter extends CustomPainter {
180+
final Animation<double> animation;
181+
final Animation<double> shadowAnimation;
182+
183+
final Color bgLightiningColor = const Color.fromARGB(255, 112, 112, 112);
184+
final Color bgLightiningColorShine = const Color.fromARGB(255, 188, 188, 188);
185+
BigCirclePainter(this.animation, this.shadowAnimation)
186+
: super(repaint: Listenable.merge([animation, shadowAnimation]));
187+
188+
@override
189+
void paint(Canvas canvas, Size size) {
190+
final Paint backgroundPaint = Paint()
191+
..color = Colors.black
192+
..style = PaintingStyle.fill;
193+
194+
canvas.drawRect(Offset.zero & size, backgroundPaint);
195+
196+
final Paint paint = Paint()
197+
..color = Color.lerp(
198+
bgLightiningColor, bgLightiningColorShine, animation.value)!
199+
..style = PaintingStyle.fill;
200+
201+
// Calculate the center of the canvas
202+
final offsetX = size.width - (size.width / 4 * animation.value);
203+
final offsetY = size.height - (size.height / 4 * animation.value);
204+
final Offset center = Offset(offsetX, offsetY);
205+
206+
final double radius = size.width * .65;
207+
208+
// Draw the circle
209+
canvas.drawCircle(center, radius, paint);
210+
211+
// Draw rect from size
212+
// final verticalOffset = (size.height) * animation.value;
213+
214+
canvas.save();
215+
// Use the custom easing function
216+
// final easedValue = customEase(animation.value);
217+
final verticalOffset = size.height * 1.0 * (1 - shadowAnimation.value);
218+
canvas.translate(0, -verticalOffset);
219+
220+
final rect = Rect.fromLTWH(0, 0, size.width, size.height);
221+
final path = Path();
222+
path.addRect(rect);
223+
224+
const gradient = LinearGradient(
225+
begin: Alignment.topRight,
226+
end: Alignment.bottomRight,
227+
stops: [0.0, .8], //from .4 to .8 animation.value]
228+
colors: [
229+
Colors.transparent,
230+
Colors.black,
231+
],
232+
);
233+
234+
Paint gradientPaint = Paint()
235+
..shader = gradient.createShader(path.getBounds());
236+
237+
canvas.drawPath(path, gradientPaint);
238+
// Restore the canvas to its original state
239+
canvas.restore();
240+
}
241+
242+
@override
243+
bool shouldRepaint(covariant CustomPainter oldDelegate) {
244+
return false;
245+
}
246+
}
247+
248+
class ReflectionWidget extends StatelessWidget {
249+
final Animation<double> animation;
250+
final Animation<double> shadowAnimation;
251+
252+
ReflectionWidget(this.animation, this.shadowAnimation);
253+
254+
@override
255+
Widget build(BuildContext context) {
256+
return Stack(
257+
children: [
258+
Container(
259+
width: double.infinity,
260+
height: double.infinity,
261+
),
262+
CustomPaint(
263+
painter: BigCirclePainter(animation, shadowAnimation),
264+
child: Container(
265+
width: double.infinity,
266+
height: double.infinity,
267+
),
268+
),
269+
],
270+
);
271+
}
272+
}

0 commit comments

Comments
 (0)