最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter繪制3.4邊形及多邊形漸變動畫實(shí)現(xiàn)示例

 更新時間:2022年08月09日 11:33:51   作者:十三點(diǎn)47  
這篇文章主要為大家介紹了Flutter繪制3.4邊形之多邊形漸變動畫實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

項(xiàng)目被優(yōu)化了,人也跟著被優(yōu)化了,正好趁這一個月整理整理關(guān)于flutter的一些東西。

繪制3.4邊形

先看一下效果圖:

起因是上上上上上個月瀏覽flutter的canvas相關(guān)內(nèi)容時,點(diǎn)進(jìn)去一個網(wǎng)站,看到一個讓我眼前一亮的動效:

作者用的代碼是swift的,我沒細(xì)看,不過他文章里的一句話讓我醍醐灌頂:

That is, we want the shape be asked to draw multiple times, each time with a different value for the sides parameter: 3, 3.1, 3.15, 3.2, 3.25, all the way to 4.

大意就是說我們想搞一個從三邊形到四邊形的動畫,我們只需要畫出3.1邊形,3.2邊形,3.3邊形,一直畫到4邊形。

這句話真的讓我醍醐灌頂,因?yàn)槲铱吹竭@個動畫,第一反應(yīng)是需要計算每個頂點(diǎn)位置,從而做出動畫;但是這句話讓這個問題脫離了具體細(xì)節(jié),將問題抽象化,數(shù)學(xué)化。只要我們定義出分?jǐn)?shù)邊形的繪制方法,我們就可以很簡單的完成這個動畫。

現(xiàn)在我們只要定義如何繪制分?jǐn)?shù)邊形就可以了。

整數(shù)邊形的繪制

在定義繪制分?jǐn)?shù)邊形的繪制方法之前,我們先來看整數(shù)邊形是如何繪制的:

繪制正三角形,我們會在圓上找出三等分點(diǎn),然后依次連接這三個點(diǎn),這就是正三角形的繪制方法。

而且繪制的時候我們通常會固定一個起點(diǎn),然后從這個起點(diǎn)開始等分。

分?jǐn)?shù)邊形的繪制

分?jǐn)?shù)邊形的繪制也是一樣的道理,比如3.1邊形的繪制,我們需要找到四個點(diǎn)

我們先固定一個起點(diǎn),然后從這個起點(diǎn)開始旋轉(zhuǎn)(2*pi/3.1)個弧度,這樣依次找到剩下三個點(diǎn),(因?yàn)椴皇堑确郑钥蛇@樣找下去可以找到無數(shù)個點(diǎn),但我們只需要找四個點(diǎn)),而且當(dāng)我們給到兩個很相近的分?jǐn)?shù),比如3.1和3.11時,3.1邊形對應(yīng)的四個點(diǎn)和3.11對應(yīng)的四個點(diǎn),由于它們的起點(diǎn)是固定的,剩下各自的三個點(diǎn)對應(yīng)的位置都是很接近的(因?yàn)?.1和3.11對應(yīng)的弧度是很接近的),這樣一直畫到4.0邊形,就完成了從三邊形到四邊形的漸變動畫。

具體代碼

獲取多邊形頂點(diǎn)

List<Offset> points = [];
List<Offset> getPolygonPoints1(double sides) {
    for (int i = 0; i < sides.ceil(); i++) {
      double x, y;
      x = radius * sin(i * 2 * pi / sides);
      y = -radius * cos(i * 2 * pi / sides);
      points.add(Offset(x, y));
    }
    return points;
}

獲取到多邊形頂點(diǎn)之后我們就可以在Custompaint的paint函數(shù)中將其繪制出來:

@override
  void paint(Canvas canvas, Size size) {
      Paint paint = Paint()
          ..color = const Color(0xFF47484B)
          ..style = PaintingStyle.stroke
          ..strokeWidth = 1
          ..isAntiAlias = true;
      List<Offset> points = getPolygonPoints1(progress);
      for (int i = 0; i < points.length; i++) {
      canvas.drawLine(
          points[i % points.length], points[(i + 1) % points.length], paint);
      }
}

可以看到效果如下:

但是如果我想要下圖這種效果,當(dāng)邊數(shù)為奇數(shù)時,頂點(diǎn)位于最上方,邊數(shù)由奇數(shù)變成偶數(shù)時,最上方的頂點(diǎn)分裂成兩個,類似下圖效果:

效果改進(jìn)1

想要達(dá)到這種效果,我們只需要將代碼改進(jìn)一下,不再固定起始點(diǎn),而是在邊數(shù)由奇數(shù)變?yōu)榕紨?shù)時,將起始點(diǎn)的弧度由(pi / sides)漸變?yōu)?,由偶數(shù)變位奇數(shù)時,起始點(diǎn)弧度由0變?yōu)?pi / sides)。

代碼如下:

List<Offset> getPolygonPoints2(double sides) {
    for (int i = 0; i < sides.ceil(); i++) {
      double x, y;
      if (sides.ceil() % 2 == 0) {
        x = radius *
            sin(lerpDouble(0, (pi / sides), sides - sides.floor())! +
                i * 2 * pi / sides);
        y = -radius *
            cos(lerpDouble(0, (pi / sides), sides - sides.floor())! +
                i * 2 * pi / sides);
      } else {
        x = radius *
            sin(lerpDouble((pi / sides), 0, sides - sides.floor())! +
                i * 2 * pi / sides);
        y = -radius *
            cos(lerpDouble((pi / sides), 0, sides - sides.floor())! +
                i * 2 * pi / sides);
      }
      points.add(Offset(x, y));
    }
    return points;
}

此時效果如下:

但是還是有些不完美,我還想讓多邊形邊數(shù)為偶數(shù)時,起始點(diǎn)是從最上方的邊的中點(diǎn)一直漸變到最上方的點(diǎn),就是下面這種效果:

效果改進(jìn)2

此時我們只需要將多邊形由偶數(shù)變?yōu)槠鏀?shù)時的起始點(diǎn)改為最上方邊線的中點(diǎn)即可。 此時代碼如下:

List<Offset> getPolygonPoints(double sides) {
    for (int i = 0; i < sides.ceil(); i++) {
      double x, y;
      if (sides.ceil() % 2 == 0) {
        if (sides.ceil() == sides) {
          x = radius * sin((pi / sides) + i * 2 * pi / sides);
          y = -radius * cos((pi / sides) + i * 2 * pi / sides);
        } else {
          x = radius *
              sin(lerpDouble(0, (pi / sides), sides - sides.floor())! +
                  i * 2 * pi / sides);
          y = -radius *
              cos(lerpDouble(0, (pi / sides), sides - sides.floor())! +
                  i * 2 * pi / sides);
        }
      } else {
        if (sides.ceil() == sides) {
          x = radius * sin(i * 2 * pi / sides);
          y = -radius * cos(i * 2 * pi / sides);
        } else {
          // 起始點(diǎn)位置單獨(dú)計算
          if (i == 0) {
            double startY = -radius * cos(pi / sides);
            double endY = -radius;
            x = 0;
            y = lerpDouble(startY, endY, sides - sides.floor())!;
          } else {
            x = radius *
                sin(lerpDouble((pi / sides), 0, sides - sides.floor())! +
                    (i - lerpDouble(1, 0, sides - sides.floor())!) *
                        2 *
                        pi /
                        sides);
            y = -radius *
                cos(lerpDouble((pi / sides), 0, sides - sides.floor())! +
                    (i - lerpDouble(1, 0, sides - sides.floor())!) *
                        2 *
                        pi /
                        sides);
          }
        }
      }
      points.add(Offset(x, y));
    }
    return points;
  }

在這個基礎(chǔ)上再畫出對角線,加上縮放,就能達(dá)到我們一開始看到的最終效果了。

一些canvas的其他小demo

關(guān)于flutter canvas的其他效果,我后面會陸續(xù)分享出來,大家喜歡的話可以關(guān)注一下~

git地址

以上就是Flutter繪制3.4邊形之多邊形漸變動畫實(shí)現(xiàn)示例的詳細(xì)內(nèi)容,更多關(guān)于Flutter繪制3.4邊形漸變動畫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS App開發(fā)中UITextField組件的常用屬性小結(jié)

    iOS App開發(fā)中UITextField組件的常用屬性小結(jié)

    這篇文章主要介紹了iOS App開發(fā)中UITextField組件的常用屬性小結(jié),文中還介紹了UITextField隱藏鍵盤及為內(nèi)容增加校驗(yàn)的兩個使用技巧,需要的朋友可以參考下
    2016-04-04
  • 模仿iOS版微信的滑動View效果

    模仿iOS版微信的滑動View效果

    比如我們常用的微信,對于Android版本,長按某個聊天好友,會彈出 標(biāo)為未讀,置頂聊天,刪除聊天 選項(xiàng);對于iOS的版本,右滑,會顯示出 標(biāo)為未讀,刪除 選項(xiàng)。這篇文章主要介紹了模仿iOS版微信的滑動View,需要的朋友可以參考下
    2019-05-05
  • iOS正確監(jiān)聽手機(jī)靜音鍵和側(cè)邊音量鍵的方法示例

    iOS正確監(jiān)聽手機(jī)靜音鍵和側(cè)邊音量鍵的方法示例

    這篇文章主要給大家介紹了關(guān)于iOS正確監(jiān)聽手機(jī)側(cè)邊音量鍵的相關(guān)資料,并且給大家分享了ios監(jiān)聽靜音鍵的示例代碼,文中介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-11-11
  • fastlane自動化打包iOS APP過程示例

    fastlane自動化打包iOS APP過程示例

    這篇文章主要為大家介紹了fastlane自動化打包iOS APP的過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • IOS 打包靜態(tài)庫詳細(xì)介紹

    IOS 打包靜態(tài)庫詳細(xì)介紹

    這篇文章主要介紹了IOS 打包靜態(tài)庫詳細(xì)介紹的相關(guān)資料,這里對打包靜態(tài)庫做了詳細(xì)的說明,并進(jìn)行了總結(jié),需要的朋友可以參考下
    2016-11-11
  • iOS開發(fā)中Subview的事件響應(yīng)以及獲取subview的方法

    iOS開發(fā)中Subview的事件響應(yīng)以及獲取subview的方法

    這篇文章主要介紹了iOS開發(fā)中Subview的事件響應(yīng)以及獲取subview的方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-09-09
  • iOS中狀態(tài)欄的基本使用方法匯總

    iOS中狀態(tài)欄的基本使用方法匯總

    在iOS開發(fā)過程中,經(jīng)常會設(shè)置狀態(tài)欄的樣式,所以下面這篇文章主要給大家介紹了關(guān)于iOS中狀態(tài)欄的基本使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • 詳解iOS之關(guān)于double/float數(shù)據(jù)計算精度問題

    詳解iOS之關(guān)于double/float數(shù)據(jù)計算精度問題

    本篇文章主要介紹了iOS之關(guān)于double/float數(shù)據(jù)計算精度問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • IOS設(shè)置按鈕為圓角的示例代碼

    IOS設(shè)置按鈕為圓角的示例代碼

    這篇文章給大家分享了IOS按鈕設(shè)置為圓角的方法,按鈕的四個角都可隨意設(shè)置為圓角,對大家開發(fā)IOS具有一定的參考借鑒價值。有需要的朋友們可以參考借鑒。
    2016-09-09
  • 詳解iOS中UIView的layoutSubviews子視圖布局方法使用

    詳解iOS中UIView的layoutSubviews子視圖布局方法使用

    這篇文章主要介紹了iOS中UIView的layoutSubviews子視圖布局方法使用,文中舉了一個layoutSubviews在iPad橫豎屏切換時被調(diào)用用來重新布局的實(shí)例,需要的朋友可以參考下
    2016-04-04

最新評論

仙居县| 安溪县| 同心县| 伊通| 沐川县| 海南省| 长顺县| 兴仁县| 伊宁市| 信宜市| 内乡县| 遂宁市| 易门县| 抚松县| 吉首市| 阿拉善左旗| 涿鹿县| 高安市| 绩溪县| 正阳县| 长武县| 拉萨市| 高邑县| 平塘县| 大姚县| 怀集县| 苍山县| 绥江县| 商城县| 光泽县| 玉田县| 崇信县| 鄱阳县| 万安县| 万载县| 南涧| 神池县| 黄平县| 洛宁县| 西吉县| 休宁县|