android js 开屏动画,利用Flutter实现“孔雀开屏”的动画效果

前言

今天分享一个类似“孔雀开屏”的动画效果,打开新的页面时,新的页面从屏幕右上角以圆形逐渐打开到全屏。

先来看下具体的效果

4cc6b13003f10cfde3aebaaa5d84e1ce.gif

不知道这种效果大家叫什么名字?如果有更合适的名字可以在评论处告诉我,下面来说下如何实现此效果。

在使用Navigator进入一个新的页面时,通常用法如下:

Navigator.of(context).push(MaterialPageRoute(

builder: (context){

return PageB();

}

));

MaterialPageRoute就包含了切换页面时的动画效果,在iOS上效果是左右滑动切换,在Android上效果是上下滑动,如果想要自定义切换效果如何实现呢?答案是使用PageRouteBuilder,用法如下:

Navigator.of(context).push(PageRouteBuilder(pageBuilder:

(BuildContext context, Animation animation,

Animation secondaryAnimation) {

...

}));

在pageBuilder函数中使用animation返回新页面的动画效果即可。

新的页面以圆形效果逐渐打开,注意并没有缩放效果,所以新的页面是被裁减的,新的页面以右上角为圆心,半径逐渐变大进行裁切,就是我们想要的效果。

通过上面的分析,使用ClipPath对新的页面进行裁切

Navigator.of(context).push(PageRouteBuilder(pageBuilder:

(BuildContext context, Animation animation,

Animation secondaryAnimation) {

return AnimatedBuilder(

animation: animation,

builder: (context, child) {

return ClipPath(

clipper: CirclePath(animation.value),

child: child,

);

},

child: PageB(),

);

}));

重点是CirclePath,这就是裁切的路径,

class CirclePath extends CustomClipper {

CirclePath(this.value);

final double value;

@override

Path getClip(Size size) {

var path = Path();

double radius =

value * sqrt(size.height * size.height + size.width * size.width);

path.addOval(Rect.fromLTRB(

size.width - radius, -radius, size.width + radius, radius));

return path;

}

@override

bool shouldReclip(CustomClipper oldClipper) {

return true;

}

}

由于Path没有直接添加圆形的API函数,因此使用椭圆方法,只需将椭圆的矩形区域设置为正方形,那么裁切出来的就是圆形。

半径的最大值并不是屏幕的宽或者高,而是屏幕的对角线长度。

由于是从右上角开始,而且裁切的矩形区域必须是正方形,所以裁切的矩形区域是超出页面区域的。

如果很多页面都用到了这个效果,可以进行封装,类似于MaterialPageRoute,封装如下:

class CirclePageRoute extends PageRoute {

CirclePageRoute({

@required this.builder,

this.transitionDuration = const Duration(milliseconds: 500),

this.opaque = true,

this.barrierDismissible = false,

this.barrierColor,

this.barrierLabel,

this.maintainState = true,

});

final WidgetBuilder builder;

@override

final Duration transitionDuration;

@override

final bool opaque;

@override

final bool barrierDismissible;

@override

final Color barrierColor;

@override

final String barrierLabel;

@override

final bool maintainState;

@override

Widget buildPage(BuildContext context, Animation animation,

Animation secondaryAnimation) {

return AnimatedBuilder(

animation: animation,

builder: (context, child) {

return ClipPath(

clipper: CirclePath(animation.value),

child: child,

);

},

child: builder(context),

);

}

}

使用

Navigator.of(context).push(CirclePageRoute(builder: (context) {

return PageB();

}));

如果你查看CupertinoPageRoute、MaterialPageRoute、PageRouteBuilder的源码,你会发现这3个都是继承自PageRoute,所以,不知不觉我们又学会了自定义路由。

总结

到此这篇关于利用Flutter实现“孔雀开屏”的动画效果的文章就介绍到这了,更多相关Flutter动画效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值