溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter怎么實現笑嘻嘻的動態表情

發布時間:2022-04-24 10:12:41 來源:億速云 閱讀:183 作者:iii 欄目:開發技術

這篇文章主要介紹“Flutter怎么實現笑嘻嘻的動態表情”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Flutter怎么實現笑嘻嘻的動態表情”文章能幫助大家解決問題。

效果如下圖所示

Flutter怎么實現笑嘻嘻的動態表情

AnimatedContainer 介紹

在實現之前,先介紹一個新組件 —— 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來實現。大的頁面結構如下:

Flutter怎么實現笑嘻嘻的動態表情

細節實現

腦袋這個很容易,直接用原型裁剪,設置尺寸和底色即可:

// 腦袋
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怎么實現笑嘻嘻的動態表情

關于“Flutter怎么實現笑嘻嘻的動態表情”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女