成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

如何實現(xiàn)一個簡單的雨滴動畫?手把手告訴你

hiYoHoo / 3159人閱讀

摘要:多帶帶來看一個雨滴動畫,其實就是一個圓圈慢慢的變大同時慢慢的變淺,最后消失。如要要做一個新的,官方建議是通過組合來實現(xiàn)。手勢識別上述基本實現(xiàn)了多個雨滴的展示和動畫,然后我們要來實現(xiàn)對用戶點擊的響應(yīng)。

本文由云+社區(qū)發(fā)表
目的

寫了幾個Flutter的demo,但是對Flutter的自定義view和動畫都不太了解,看到一個類似效果在android的實現(xiàn),就嘗試用Flutter做一下。同時也是學(xué)習(xí)Flutter的自定義view和動畫相關(guān)的知識。

效果

效果動圖

在藍(lán)色區(qū)域點擊,會產(chǎn)品水波紋動畫。

宛如水珠落在池塘,雨滴落在青青草地~
思路

動畫很簡單,雖然有多個雨滴,不過每次點擊都是重復(fù)的動畫,所以只用管一個雨滴動畫是怎么實現(xiàn)的,其他的都是重復(fù)。

多帶帶來看一個雨滴動畫,其實就是一個圓圈慢慢的變大同時慢慢的變淺,最后消失。

所以我們封裝一套上述的動畫邏輯,然后在用戶每次點擊時生成一個相應(yīng)的動畫即可。

實現(xiàn) 自定義view

首先我們要解決的是自定義view的問題,我們知道Flutter中的一起UI皆Flutter,但是不同于android中的View會直接提供一個draw方法讓你做自由的繪制操作。在Flutter中,除了StatefuleWidget等申明了支持繼承的類外,其他的都是不建議繼承重寫的。如要要做一個新的Widget,官方建議是通過組合Widget來實現(xiàn)。

當(dāng)然對于我們這里這種需要自己做繪制操作的,就不是組合可以解決的了,這種情況下,F(xiàn)lutter提供了CustomPainter類,這個類提供了paint方法,可以通過重寫該方法,實現(xiàn)對canvas的繪制。然后作為CustomPaint的參數(shù),控制該Widget的展示樣式。

這里由于主要的繪制是水紋,要實現(xiàn)多個重復(fù)動畫,所以具體的繪制邏輯封裝了起來

class RainDrop extends CustomPainter {
  RainDrop(this.rainList);

  List rainList = List(); // 雨點列表
  Paint _paint = new Paint()..style = PaintingStyle.stroke; // 配置畫筆

  @override
  void paint(Canvas canvas, Size size) {
    rainList.forEach((item) {
      item.drawRainDrop(canvas, _paint); // 實際的繪制邏輯
    });
    rainList.removeWhere((item) { // 移出無效對象
      return !item.isValid();
    });
  }
  // ...
}
水紋圈的繪制

每一個水紋的動畫都是一樣的,所以統(tǒng)一封裝了起來。

class RainDropDrawer {
  static const double MAX_RADIUS = 30;
  double posX;
  double posY;
  double radius = 5;

  RainDropDrawer(this.posX, this.posY); // (2)

  drawRainDrop(Canvas canvas, Paint paint) { // (1)
    double opt = (MAX_RADIUS - radius) / MAX_RADIUS; // (3)
    paint.color = Color.fromRGBO(0, 0, 0, opt);
    canvas.drawCircle(Offset(posX, posY), radius, paint); // (4)
    radius += 0.5;
  }

  bool isValid() { // (5)
    return radius < MAX_RADIUS;
  }
}

注釋(1)處,上文提到的CustomPainter會把canvas傳過來,在這里完成單個水紋的繪制工作。

注釋(2)處,每個水紋圈需要確定的是位置,只要位置就行了,大小是隨著時間均勻擴(kuò)大的,給默認(rèn)起始值就行。

注釋(3)處,透明度是隨著半徑擴(kuò)大而逐漸透明的,這里簡單的做了線性的映射。

注釋(4)處,繪制水紋圈,然后讓水紋半徑自增,實現(xiàn)每次繪制擴(kuò)大的效果。

注釋(5)處,給定失效的條件。超過一定半徑這個水紋就消失了。

擴(kuò)散動畫

Flutter中提供了很多的動畫實現(xiàn),這里用到的是AnimationController。

其實AnimationController在這里就是提供了一個回調(diào),每次收到vsync信號時回調(diào)做一次更新。

    _animation = new AnimationController(
      // 因為是repeat的,這里的duration其實不care
        duration: const Duration(milliseconds: 200),
        vsync: this)
      ..addListener(() {
        if (_rainList.isEmpty) { //(1)
          _animation.stop();
        }
        setState(() {});
      });

這里的動畫是通過repeat啟動的,所以不用太關(guān)心duration,因為只要不手動關(guān)閉實際上是會一直回調(diào)的。

vsync設(shè)置的是當(dāng)前的widget,提供了一個ticker,會定時回調(diào)。然后在回調(diào)中setState讓當(dāng)前widget更新UI。

注釋(1)處是動畫停止的條件判斷,當(dāng)每次點擊往_rainList中加一個對象,每個對象繪制會判斷大小是否有效,如果無效會被從列表中移出,當(dāng)列表中沒有元素時就停止動畫。

手勢識別

上述基本實現(xiàn)了多個雨滴的展示和動畫,然后我們要來實現(xiàn)對用戶點擊的響應(yīng)。

Flutter提供了GestureDetector這個widget來做手勢識別。所以我們只需要用這個widget wrap住我們的自定義view,然后實現(xiàn)對應(yīng)的手勢監(jiān)聽方法即可。

      GestureDetector(
        onTapUp: (TapUpDetails tapUp) {
          RenderBox getBox = context.findRenderObject();
          var localOffset = getBox.globalToLocal(tapUp.globalPosition); // (1)

          var rainDrop = RainDropDrawer(localOffset.dx, localOffset.dy);
          _rainList.add(rainDrop);
          _animation.repeat(); // (2)
        },
        child: CustomPaint(
          painter: RainDrop(_rainList),
        ),
      ),

這里我們關(guān)注用戶輕點后抬起的手勢,這個監(jiān)聽的方法會傳入TapUpDetails參數(shù),這個參數(shù)含有抬起的位置參數(shù),但是需要注意的是,這個坐標(biāo)是全屏幕的坐標(biāo),而繪制的坐標(biāo)是widget內(nèi)的坐標(biāo),所以我們需要將這個坐標(biāo)轉(zhuǎn)換為我們widget內(nèi)的坐標(biāo)系,F(xiàn)lutter提供了這樣的一個工具方法,參考注釋(1)處的實現(xiàn)即可。

完成了坐標(biāo)換算,就可以構(gòu)建一個“雨點”對象,添加到List里面。然后在注釋(2)處啟動動畫,就可以看到我們文章開頭的動畫效果啦~

總結(jié)

Flutter的動畫實現(xiàn)起來真的很簡單,提供一個差值回調(diào),然后不停的更新即可。不過這里暫時沒有考慮性能等問題,對setState這個方法感覺還是很黑盒,不太懂Flutter具體的UI刷新原理。

后面會梳理一下這類原理知識,否則還是有點擔(dān)憂復(fù)雜動畫按這種寫法是否會卡頓。

此文已由作者授權(quán)騰訊云+社區(qū)發(fā)布

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100462.html

相關(guān)文章

  • Canvas制作下雨動畫

    摘要:簡介在上看到一個做的下雨效果動畫,感覺蠻有意思的。讓瀏覽器要重繪時調(diào)用你指定的方法來繪制你的動畫。殘影的繪制可以說是雨滴下落的關(guān)鍵。用來繪制動畫的效果確實能讓人眼前一亮,讓的視覺效果提升一大截。發(fā)動自己的智慧,相信能做出更多奇妙的動畫。 簡介 在codepen上看到一個Canvas做的下雨效果動畫,感覺蠻有意思的。就研究了下,這里來分享下,實現(xiàn)技巧。效果可以見下面的鏈接。 霓虹雨: h...

    Carson 評論0 收藏0
  • Canvas制作下雨動畫

    摘要:簡介在上看到一個做的下雨效果動畫,感覺蠻有意思的。讓瀏覽器要重繪時調(diào)用你指定的方法來繪制你的動畫。殘影的繪制可以說是雨滴下落的關(guān)鍵。發(fā)動自己的智慧,相信能做出更多奇妙的動畫。轉(zhuǎn)載出處前端開發(fā)制作的下雨動畫簡介 在codepen上看到一個Canvas做的下雨效果動畫,感覺蠻有意思的。就研究了下,這里來分享下,實現(xiàn)技巧。效果可以見下面的鏈接。 霓虹雨:http://codepen.io/nate...

    番茄西紅柿 評論0 收藏0
  • canvas實現(xiàn) 漂亮下雨效果

    摘要:說明這篇文章說如何用畫出漂亮的下雨效果,先看看最后實現(xiàn)的效果吧。 說明 這篇文章說如何用canvas畫出漂亮的下雨效果,先看看最后實現(xiàn)的效果吧。 效果圖showImg(https://segmentfault.com/img/bV8ITm?w=936&h=532); 解釋 看圖來分析下,我們需要實現(xiàn)哪些效果。1、雨滴下落效果,移動鼠標(biāo)控制下落方向 2、雨滴下落散成小水珠,小水珠的移動...

    Jonathan Shieber 評論0 收藏0
  • 用 Matplotlib 庫生成動畫圖表

    摘要:相對于靜態(tài)圖表,人類總是容易被動畫和交互式圖表所吸引??梢允褂幂p松生成圖表直方圖功率譜,條形圖,錯誤圖表,散點圖等。然而,也有一些方面落后于同類的庫。動畫使用一組固定的對象。稍后將用數(shù)據(jù)對行對象進(jìn)行填充。現(xiàn)在用將它們轉(zhuǎn)換為動畫。 翻譯:瘋狂的技術(shù)宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...

    call_me_R 評論0 收藏0
  • 用 Matplotlib 庫生成動畫圖表

    摘要:相對于靜態(tài)圖表,人類總是容易被動畫和交互式圖表所吸引。可以使用輕松生成圖表直方圖功率譜,條形圖,錯誤圖表,散點圖等。然而,也有一些方面落后于同類的庫。動畫使用一組固定的對象。稍后將用數(shù)據(jù)對行對象進(jìn)行填充。現(xiàn)在用將它們轉(zhuǎn)換為動畫。 翻譯:瘋狂的技術(shù)宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...

    不知名網(wǎng)友 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<