@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
8
8
import 'package:fx_2_folder/vinyl/camera_simulation.dart' ;
9
9
import 'package:fx_2_folder/vinyl/card_stack_4_angles.dart' ;
10
10
import 'package:fx_2_folder/vinyl/easing/super_duper_ease_in.dart' ;
11
+ import 'package:fx_2_folder/vinyl/exmaples/glass_card.dart' ;
11
12
import 'package:fx_2_folder/vinyl/exmaples/spring_examples.dart' ;
12
13
import 'package:fx_2_folder/vinyl/exmaples/spring_playground.dart' ;
13
14
import 'package:fx_2_folder/vinyl/transform_examples.dart' ;
@@ -26,7 +27,10 @@ class VinylHomeWidget extends StatelessWidget {
26
27
// body: TransformDemo(),
27
28
28
29
// body: SpringAnimationsPage(),
30
+
29
31
body: TransformApp (),
32
+ // body: GlassCardPage(),
33
+
30
34
// body: SpringAnimationsDemo(),
31
35
);
32
36
}
@@ -50,6 +54,9 @@ class _TransformAppState extends State<TransformApp>
50
54
late AnimationController animParentController;
51
55
late Animation <double > _headBowForwardAnimation;
52
56
57
+ late AnimationController vinylController;
58
+ late Animation <double > _vinylJumpAnimation;
59
+
53
60
final List <VinylItem > _vinylItems = List .from (vinylItems);
54
61
55
62
String firstVinylId = vinylItems[0 ].id;
@@ -102,7 +109,7 @@ class _TransformAppState extends State<TransformApp>
102
109
..rotateY (323 * pi / 180 ) // horixontal
103
110
..rotateX (baseRotationX +
104
111
sin (_headBowForwardAnimation.value * pi) *
105
- 5 *
112
+ 10 *
106
113
pi /
107
114
180 +
108
115
_rotateX) // vertical
@@ -163,12 +170,15 @@ class _TransformAppState extends State<TransformApp>
163
170
_combinedVerticalAnimation,
164
171
_topJumpAnimation,
165
172
_topMoveForwardAnimation,
173
+ _vinylJumpAnimation,
166
174
]),
167
175
builder: (context, child) {
168
176
return Stack (
169
177
children: List .generate (_vinylItems.length, (index) {
170
178
var vinylItem = _vinylItems[index];
171
179
// if (vinylItem.id == 'vinyl_3') {
180
+ bool isSecond =
181
+ false ; // At this moment, the second card is the first one in the stack
172
182
if (vinylItem.id == vinylOrder[0 ]) {
173
183
vinylItem.verticalAnimationValue =
174
184
_combinedVerticalAnimation.value;
@@ -177,6 +187,7 @@ class _TransformAppState extends State<TransformApp>
177
187
vinylItem.rotateX = _flipAnimation.value;
178
188
// } else if (_vinylItems[index].id == 'vinyl_2') {
179
189
} else if (_vinylItems[index].id == vinylOrder[1 ]) {
190
+ isSecond = true ;
180
191
vinylItem.verticalAnimationValue = _topJumpAnimation.value;
181
192
vinylItem.zPositionValue = - 50.0 + _topMoveForwardAnimation.value;
182
193
vinylItem.rotateX = 0.0 ;
@@ -190,20 +201,57 @@ class _TransformAppState extends State<TransformApp>
190
201
191
202
return Transform (
192
203
transform: Matrix4 .identity ()
204
+ ..setEntry (3 , 2 , 0.001 )
193
205
..translate (0.0 , vinylItem.verticalAnimationValue,
194
206
vinylItem.zPositionValue)
195
207
..rotateX (vinylItem.rotateX),
196
208
alignment: Alignment .center, // -index * 50.0
197
- child: Container (
198
- width: 200 ,
199
- height: 200 ,
200
- color: _vinylItems[index].color,
201
- child: Center (
202
- child: Text (
203
- 'Layer ${index + 1 } + id ${_vinylItems [index ].id }' ,
204
- style: TextStyle (color: Colors .white),
209
+ child: Stack (
210
+ children: [
211
+ // Container(
212
+ // width: 200,
213
+ // height: 200,
214
+ // color: _vinylItems[index].color,
215
+ // child: Text(
216
+ // 'Layer ${index + 1} + id ${_vinylItems[index].id}',
217
+ // style: TextStyle(color: Colors.white),
218
+ // ),
219
+ // ),
220
+ Container (
221
+ width: 200 ,
222
+ height: 200 ,
223
+ child: Image .asset (
224
+ vinylItem.asset,
225
+ fit: BoxFit .fill,
226
+ ),
205
227
),
206
- ),
228
+ Transform .translate (
229
+ offset: Offset (
230
+ 0 ,
231
+ isSecond
232
+ ? _vinylJumpAnimation.value
233
+ : 0 ), // Move up and down
234
+ child: Container (
235
+ width: 200 ,
236
+ height: 200 ,
237
+ // color: _vinylItems[index].color,
238
+ child: Image .asset (
239
+ "assets/images/vinyl/vinyl.png" ,
240
+ fit: BoxFit .fill,
241
+ ),
242
+ ),
243
+ ),
244
+
245
+ if (isFrontImage (vinylItem.rotateX))
246
+ Container (
247
+ width: 200 ,
248
+ height: 200 ,
249
+ child: Image .asset (
250
+ vinylItem.asset,
251
+ fit: BoxFit .fill,
252
+ ),
253
+ ),
254
+ ],
207
255
),
208
256
);
209
257
}),
@@ -212,6 +260,12 @@ class _TransformAppState extends State<TransformApp>
212
260
);
213
261
}
214
262
263
+ bool isFrontImage (double angle) {
264
+ const degrees90 = pi / 2 ;
265
+ const degrees270 = 3 * pi / 2 ;
266
+ return angle <= degrees90 || angle >= degrees270;
267
+ }
268
+
215
269
void resetAnimation () {
216
270
animController.dispose ();
217
271
animParentController.dispose ();
@@ -228,10 +282,13 @@ class _TransformAppState extends State<TransformApp>
228
282
229
283
initAnimations () {
230
284
animController = AnimationController (
231
- vsync: this , duration: const Duration (milliseconds: 1000 ))
285
+ vsync: this , duration: const Duration (milliseconds: 1200 ))
232
286
..addListener (_animationHooks);
233
287
234
288
animParentController = AnimationController (
289
+ vsync: this , duration: const Duration (milliseconds: 600 ));
290
+
291
+ vinylController = AnimationController (
235
292
vsync: this , duration: const Duration (milliseconds: 300 ));
236
293
237
294
// Add a status listener
@@ -249,23 +306,25 @@ class _TransformAppState extends State<TransformApp>
249
306
animController.forward ();
250
307
}
251
308
});
309
+ // Start the animation and reverse it
310
+ // _controller.forward().then((_) => _controller.reverse());
252
311
253
312
// Combine vertical animations on the first Vinyl!
254
313
_combinedVerticalAnimation = TweenSequence <double >([
255
314
TweenSequenceItem (
256
315
tween: Tween <double >(begin: 0.0 , end: 150.0 )
257
316
.chain (CurveTween (curve: Curves .linear)),
258
- weight: 25 .0 ,
317
+ weight: 30 .0 ,
259
318
),
260
319
TweenSequenceItem (
261
320
tween: Tween <double >(begin: 150.0 , end: 150.0 )
262
321
.chain (CurveTween (curve: Curves .linear)),
263
- weight: 50 .0 ,
322
+ weight: 40 .0 ,
264
323
),
265
324
TweenSequenceItem (
266
325
tween: Tween <double >(begin: 150.0 , end: 0.0 )
267
326
.chain (CurveTween (curve: Curves .linear)),
268
- weight: 25 .0 ,
327
+ weight: 30 .0 ,
269
328
),
270
329
]).animate (animController);
271
330
@@ -276,17 +335,17 @@ class _TransformAppState extends State<TransformApp>
276
335
TweenSequenceItem (
277
336
tween: Tween <double >(begin: 0.0 , end: pi / 2 )
278
337
.chain (CurveTween (curve: Curves .linear)),
279
- weight: 25 .0 ,
338
+ weight: 30 .0 ,
280
339
),
281
340
TweenSequenceItem (
282
341
tween: Tween <double >(begin: pi / 2 , end: 3 * pi / 2 )
283
342
.chain (CurveTween (curve: Curves .linear)),
284
- weight: 50 .0 ,
343
+ weight: 40 .0 ,
285
344
),
286
345
TweenSequenceItem (
287
346
tween: Tween <double >(begin: 3 * pi / 2 , end: 2 * pi)
288
347
.chain (CurveTween (curve: Curves .linear)),
289
- weight: 25 .0 ,
348
+ weight: 30 .0 ,
290
349
),
291
350
]).animate (animController);
292
351
@@ -327,9 +386,17 @@ class _TransformAppState extends State<TransformApp>
327
386
_headBowForwardAnimation = Tween <double >(begin: 0 , end: 1 ).animate (
328
387
CurvedAnimation (
329
388
parent: animParentController,
330
- curve: SnappySpringCurve () //BouncyElasticCurve()
389
+ curve: Interval (0.0 , 0.75 ,
390
+ curve: SnappySpringCurve ()) //BouncyElasticCurve()
331
391
),
332
392
);
393
+
394
+ _vinylJumpAnimation = Tween <double >(begin: 0 , end: - 50 ).animate (
395
+ CurvedAnimation (
396
+ parent: vinylController,
397
+ curve: Interval (0.0 , 1.0 , curve: SnappySpringCurve ()),
398
+ ),
399
+ );
333
400
}
334
401
335
402
Widget _buildSlider ({
@@ -359,6 +426,8 @@ class _TransformAppState extends State<TransformApp>
359
426
_isStackReordered = true ;
360
427
} else if (animController.value < 0.5 ) {
361
428
_isStackReordered = false ;
429
+ } else if (animController.value > 0.74 ) {
430
+ vinylController.forward ().then ((_) => vinylController.reverse ());
362
431
}
363
432
}
364
433
@@ -384,13 +453,15 @@ class _TransformAppState extends State<TransformApp>
384
453
class VinylItem {
385
454
final String id;
386
455
final Color color;
456
+ final String asset;
387
457
double verticalAnimationValue = 0.0 ;
388
458
double zPositionValue = 0.0 ;
389
459
double rotateX = 0.0 ;
390
460
391
461
VinylItem (
392
462
{required this .id,
393
463
required this .color,
464
+ required this .asset,
394
465
this .verticalAnimationValue = 0.0 ,
395
466
this .zPositionValue = 0.0 ,
396
467
this .rotateX = 0.0 });
@@ -405,18 +476,21 @@ final List<VinylItem> vinylItems = [
405
476
VinylItem (
406
477
id: 'vinyl_1' ,
407
478
color: Colors .green,
479
+ asset: "assets/images/vinyl/cover_1.png" ,
408
480
verticalAnimationValue: 0.0 ,
409
481
zPositionValue: 0.0 ,
410
482
rotateX: 0.0 ),
411
483
VinylItem (
412
484
id: 'vinyl_2' ,
413
485
color: Colors .yellow,
486
+ asset: "assets/images/vinyl/cover_2.png" ,
414
487
verticalAnimationValue: 0.0 ,
415
488
zPositionValue: 0.0 ,
416
489
rotateX: 0.0 ),
417
490
VinylItem (
418
491
id: 'vinyl_3' ,
419
492
color: Colors .purple,
493
+ asset: "assets/images/vinyl/cover_3.png" ,
420
494
verticalAnimationValue: 0.0 ,
421
495
zPositionValue: 0.0 ,
422
496
rotateX: 0.0 ),
0 commit comments