我正在尝试使用第一个视图中心的圆圈进行页面转换,该圆圈展开后显示第二个视图。
或者,如果我使用中心有透明孔的小部件(我们可以通过该孔看到底部小部件),并且使用扩展孔以显示底部小部件的动画,情况是一样的。
我发现的唯一与我想要做的类似的答案是:
但我无法使用小部件代替圆 ping 屏幕中心。
使用
HoleMaterialPageRoute
而不是 MaterialPageRoute
- 请注意,如果默认持续时间适合您,您可以完全删除 transitionDuration
,您也可以删除 late final curve = CurvedAnimation(
并使用 animation.value
代替 curve.value
,但在我看来非线性半径增长看起来更好:-)
class HoleMaterialPageRoute extends MaterialPageRoute {
HoleMaterialPageRoute({required super.builder});
// the default transitionDuration is Duration(milliseconds: 300) so you can make
// it longer to see the better effect:
@override
Duration get transitionDuration => const Duration(milliseconds: 800);
@override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
return ClipPath(
clipper: _HoleClipper(animation),
child: child,
);
}
}
class _HoleClipper extends CustomClipper<Path> {
_HoleClipper(this.animation) : super(reclip: animation);
final Animation<double> animation;
late final curve = CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
reverseCurve: Curves.easeIn,
);
@override
Path getClip(Size size) {
final center = size.center(Offset.zero);
final radius = lerpDouble(0, center.distance, curve.value)!;
// print('size: $size, radius: $radius');
final oval = Rect.fromCircle(center: center, radius: radius);
return Path()
..addOval(oval);
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}