美文网首页Flutter圈子Flutter中文社区Flutter
Flutter “孔雀开屏”的动画效果

Flutter “孔雀开屏”的动画效果

作者: 老孟程序员 | 来源:发表于2020-05-24 19:50 被阅读0次

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

先来看下具体的效果

ping

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

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

Navigator.of(context).push(MaterialPageRoute(
  builder: (context){
    return PageB();
  }
));

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

Navigator.of(context).push(PageRouteBuilder(pageBuilder:
    (BuildContext context, Animation<double> animation,
        Animation<double> secondaryAnimation) {
  ...
}));

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

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

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

Navigator.of(context).push(PageRouteBuilder(pageBuilder:
    (BuildContext context, Animation<double> animation,
        Animation<double> secondaryAnimation) {
  return AnimatedBuilder(
    animation: animation,
    builder: (context, child) {
      return ClipPath(
        clipper: CirclePath(animation.value),
        child: child,
      );
    },
    child: PageB(),
  );
}));

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

class CirclePath extends CustomClipper<Path> {
  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<Path> 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<double> animation,
      Animation<double> 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();
}));

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

交流

老孟Flutter博客地址(近200个控件用法):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

相关文章

  • Flutter “孔雀开屏”的动画效果

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

  • flutter常用控件用法收藏

    flutter圆角效果实现 outlineButton 头部折叠动画效果 flutter按钮shape设置 Flu...

  • Flutter动画相关

    Flutter 动画曲线Curves 效果一览

  • 深入理解Flutter动画原理

    基于Flutter 1.5,从源码视角来深入剖析flutter动画原理,相关源码目录见文末附录 一、概述 动画效果...

  • Flutter轮播图

    前端开发当中最有意思的就是实现动画特效,Flutter提供的各种动画组件可以方便实现各种动画效果。Flutter中...

  • Flutter 动画效果

    在动画方面 Flutter 提供了 Animation 类提供使用。 动画 Flutter 中创建动画,请创建名为...

  • Flutter 基础动画 Hero动画 交错动画

    Flutter动画学习效果直接贴代码 运行看吧,更改push入口查看不同动画效果。基础动画:颜色渐变、控件大小更改...

  • Flutter EasyLoading - 让全局Toast/L

    ✨flutter_easyloading: 一个简单易用的Flutter插件,包含23种loading动画效果、进...

  • flutter动画

    动画 效果图: flutter中,动画可以当成一个时间内对应值的变化刷新Widget来达到动画的效果类似Andro...

  • 【Flutter 实战】酷炫的开关动画效果

    此动画效果是我在浏览文章时发现的一个非常酷炫的效果,于是就使用 Flutter 实现了。更多动画效果及Flutte...

网友评论

    本文标题:Flutter “孔雀开屏”的动画效果

    本文链接:https://www.haomeiwen.com/subject/vyojahtx.html