-
-
Notifications
You must be signed in to change notification settings - Fork 493
/
hero.dart
99 lines (92 loc) · 3.41 KB
/
hero.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import 'package:flutter/material.dart';
import 'package:extended_image/extended_image.dart';
/// make hero better when slide out
class HeroWidget extends StatefulWidget {
const HeroWidget({
required this.child,
required this.tag,
required this.slidePagekey,
this.slideType = SlideType.onlyImage,
});
final Widget child;
final SlideType slideType;
final Object tag;
final GlobalKey<ExtendedImageSlidePageState> slidePagekey;
@override
_HeroWidgetState createState() => _HeroWidgetState();
}
class _HeroWidgetState extends State<HeroWidget> {
late RectTween _rectTween;
@override
Widget build(BuildContext context) {
return Hero(
tag: widget.tag,
createRectTween: (Rect? begin, Rect? end) {
_rectTween = RectTween(begin: begin, end: end);
return _rectTween;
},
// make hero better when slide out
flightShuttleBuilder: (BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext) {
// make hero more smoothly
final Hero hero = (flightDirection == HeroFlightDirection.pop
? fromHeroContext.widget
: toHeroContext.widget) as Hero;
if (flightDirection == HeroFlightDirection.pop) {
final bool fixTransform = widget.slideType == SlideType.onlyImage &&
(widget.slidePagekey.currentState!.offset != Offset.zero ||
widget.slidePagekey.currentState!.scale != 1.0);
final Widget toHeroWidget = (toHeroContext.widget as Hero).child;
return AnimatedBuilder(
animation: animation,
builder: (BuildContext buildContext, Widget? child) {
Widget animatedBuilderChild = hero.child;
// make hero more smoothly
animatedBuilderChild = Stack(
clipBehavior: Clip.antiAlias,
alignment: Alignment.center,
children: <Widget>[
Opacity(
opacity: 1 - animation.value,
child: UnconstrainedBox(
child: SizedBox(
width: _rectTween.begin!.width,
height: _rectTween.begin!.height,
child: toHeroWidget,
),
),
),
Opacity(
opacity: animation.value,
child: animatedBuilderChild,
)
],
);
// fix transform when slide out
if (fixTransform) {
final Tween<Offset> offsetTween = Tween<Offset>(
begin: Offset.zero,
end: widget.slidePagekey.currentState!.offset);
final Tween<double> scaleTween = Tween<double>(
begin: 1.0, end: widget.slidePagekey.currentState!.scale);
animatedBuilderChild = Transform.translate(
offset: offsetTween.evaluate(animation),
child: Transform.scale(
scale: scaleTween.evaluate(animation),
child: animatedBuilderChild,
),
);
}
return animatedBuilderChild;
},
);
}
return hero.child;
},
child: widget.child,
);
}
}