您好,登錄后才能下訂單哦!
小編這次要給大家分享的是利用Flutter如何實(shí)現(xiàn)“孔雀開屏”動畫效果,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
前言
今天分享一個(gè)類似“孔雀開屏”的動畫效果,打開新的頁面時(shí),新的頁面從屏幕右上角以圓形逐漸打開到全屏。
先來看下具體的效果
不知道這種效果大家叫什么名字?如果有更合適的名字可以在評論處告訴我,下面來說下如何實(shí)現(xiàn)此效果。
在使用Navigator進(jìn)入一個(gè)新的頁面時(shí),通常用法如下:
Navigator.of(context).push(MaterialPageRoute( builder: (context){ return PageB(); } ));
MaterialPageRoute就包含了切換頁面時(shí)的動畫效果,在iOS上效果是左右滑動切換,在Android上效果是上下滑動,如果想要自定義切換效果如何實(shí)現(xiàn)呢?答案是使用PageRouteBuilder,用法如下:
Navigator.of(context).push(PageRouteBuilder(pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { ... }));
在pageBuilder函數(shù)中使用animation返回新頁面的動畫效果即可。
新的頁面以圓形效果逐漸打開,注意并沒有縮放效果,所以新的頁面是被裁減的,新的頁面以右上角為圓心,半徑逐漸變大進(jìn)行裁切,就是我們想要的效果。
通過上面的分析,使用ClipPath對新的頁面進(jìn)行裁切
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(), ); }));
重點(diǎn)是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函數(shù),因此使用橢圓方法,只需將橢圓的矩形區(qū)域設(shè)置為正方形,那么裁切出來的就是圓形。
半徑的最大值并不是屏幕的寬或者高,而是屏幕的對角線長度。
由于是從右上角開始,而且裁切的矩形區(qū)域必須是正方形,所以裁切的矩形區(qū)域是超出頁面區(qū)域的。
如果很多頁面都用到了這個(gè)效果,可以進(jìn)行封裝,類似于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(); }));
如果你查看CupertinoPageRoute、MaterialPageRoute、PageRouteBuilder的源碼,你會發(fā)現(xiàn)這3個(gè)都是繼承自PageRoute,所以,不知不覺我們又學(xué)會了自定義路由。
看完這篇關(guān)于利用Flutter如何實(shí)現(xiàn)“孔雀開屏”動畫效果的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。