這篇文章主要介紹“Flutter怎么實現笑嘻嘻的動態表情”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter怎么實現笑嘻嘻的動態表情”文章能幫助大家解決問題。
效果如下圖所示
在實現之前,先介紹一個新組件 —— AnimatedContainer
??催@個名字就知道和 Container
有關,實際上AnimatedContainer
是 Flutter 中的一個動畫容器,Container
有的屬性基本上它都有,我們看一下二者的構造方法的區別。
AnimatedContainer({ Key? key, this.alignment, this.padding, Color? color, Decoration? decoration, this.foregroundDecoration, double? width, double? height, BoxConstraints? constraints, this.margin, this.transform, this.transformAlignment, this.child, this.clipBehavior = Clip.none, Curve curve = Curves.linear, required Duration duration, VoidCallback? onEnd, }); Container({ Key? key, this.alignment, this.padding, this.color, this.decoration, this.foregroundDecoration, double? width, double? height, BoxConstraints? constraints, this.margin, this.transform, this.transformAlignment, this.child, this.clipBehavior = Clip.none, });
可以看到,實際上 AnimatedContainer
和 Container
只差了3個屬性,而這三個屬性就是控制動畫的參數:
curve
:動畫曲線,默認是線性;
duration
:動效時長參數;
onEnd
:動效結束后的回調方法。
AnimatedContainer
的特性是所有涉及外觀的屬性都會生成一個過渡動效,當這些外觀屬性發生改變的時候就會使用生成的的動效來完成過渡,從而展現出動畫效果。像我們要實現的笑嘻嘻的表情其實就是利用 AnimatedContainer
實現的。
我們的笑嘻嘻動效,底部是一個圓形腦袋,上面有兩顆眼睛和一個嘴巴,其中眼睛和嘴巴有移動動效,而眼睛的眼珠還有方向的動效。這些動效都可以使用AnimatedContainer
來實現。大的頁面結構如下:
腦袋這個很容易,直接用原型裁剪,設置尺寸和底色即可:
// 腦袋 ClipOval( child: Container( width: 120, height: 120, color: Colors.blue, ), ),
眼睛左眼和右眼有點不一樣,眼球實際就是AnimatedContainer
使用 borderRadius
裁剪為圓形,而眼珠是AnimatedContainer
的子組件 —— 黑色的圓圈。具體實現向左或向右看使用一個變量 seeLeft
控制,而向左向右的轉換過渡效果都由 AnimatedContainer
控制。
seeLeft = true
,向左看:眼珠對齊的方式是 bottomLeft
,左眼縱向方向上稍微往下移一點;右眼往左移動一定的位置,這樣就會有向左看的效果了;
seeLeft = false
,向右看:眼珠對齊的方式是 bottomRight
,右眼縱向方向上稍微往下移一點;左眼往右移動一定的位置,這樣就會有向右看的效果了;
實現代碼如下:
// 左眼 Positioned( top: marginTop, left: marginLR, child: AnimatedContainer( alignment: seeLeft ? Alignment.bottomLeft : Alignment.bottomRight, padding: EdgeInsets.all(eyePadding), transform: Matrix4.identity() ..translate( seeLeft ? 0.0 : sideOffset, seeLeft ? eyeOffset : 0.0, 0), duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn, width: eyeSize, height: eyeSize, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(eyeSize / 2), ), child: ClipOval( child: Container( color: Colors.black, width: eyeBallSize, height: eyeBallSize, ), ), ), ), // 右眼 Positioned( top: marginTop, right: marginLR, child: AnimatedContainer( alignment: seeLeft ? Alignment.bottomLeft : Alignment.bottomRight, padding: EdgeInsets.all(eyePadding), transform: Matrix4.identity() ..translate(seeLeft ? -sideOffset : 0.0, seeLeft ? 0.0 : eyeOffset, 0), duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn, width: eyeSize, height: eyeSize, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(eyeSize / 2), ), child: ClipOval( child: Container( color: Colors.black, width: eyeBallSize, height: eyeBallSize, ), ), ), ),
這里的眼珠對齊使用的就是AnimatedContainer
的 alignment
參數控制,而眼球的位置使用 Matrix4
的平移實現:
Matrix4.identity() ..translate(seeLeft ? -sideOffset : 0.0, seeLeft ? 0.0 : eyeOffset, 0),
笑臉的實現使用ClipPath
,繪制兩條弧線就可以了,然后平移的幅度和眼珠保持一致,就可以感覺是轉頭的效果了,AnimatedContainer
部分的代碼如下:
// 笑嘻嘻的嘴巴 Positioned( bottom: 10, height: 40, left: 0, child: AnimatedContainer( alignment: seeLeft ? Alignment.bottomLeft : Alignment.bottomRight, padding: EdgeInsets.all(4.0), transform: Matrix4.identity() ..translate(seeLeft ? 25.0 : 35.0, 0, 0), duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn, child: ClipPath( clipper: SmileClipPath(), child: Container( width: 60, height: 40, color: Colors.yellow, ), ), ), ),
笑嘻嘻的嘴巴的裁剪類 SmileClipPath
代碼如下:
class SmileClipPath extends CustomClipper<Path> { @override Path getClip(Size size) { return Path() ..moveTo(0, 0) ..arcToPoint( Offset(size.width, 0), radius: Radius.circular(size.width * 0.55), clockwise: false, ) ..arcToPoint( Offset(0, 0), radius: Radius.circular(size.width), clockwise: true, ); } @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) { return false; } }
最后,控制狀態變量 seeLeft
的變化通過一個按鈕點擊觸發就好了。
floatingActionButton: FloatingActionButton( child: Icon(Icons.play_arrow, color: Colors.white), onPressed: () { setState(() { seeLeft = !seeLeft; }); }, ),
最終運行效果如下,完整代碼已提交至:動畫相關代碼。
關于“Flutter怎么實現笑嘻嘻的動態表情”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。