Flutter 貝塞爾曲線實(shí)現(xiàn)案例

前言:

各位同學(xué)大家好,有段時(shí)間沒有給大家更新文章了,趁著今天有時(shí)間我們就給大家分享一個(gè)flutter的貝塞爾曲線的繪制的案例,希望能幫助到各位同學(xué)的學(xué)習(xí)和工作,那么廢話不多說我們正式開始 。

準(zhǔn)備工作 :

需要安裝flutter的開發(fā)環(huán)境:大家可以去看看之前的教程:
1 win系統(tǒng)flutter開發(fā)環(huán)境安裝教程: http://www.itdecent.cn/p/152447bc8718
2 mac系統(tǒng)flutter開發(fā)環(huán)境安裝教程:http://www.itdecent.cn/p/bad2c35b41e3

效果圖:

QQ截圖20201116103638.png

QQ截圖20201116103620.png

具體實(shí)現(xiàn):

普通貝塞爾曲線

QQ截圖20201116112103.png
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: Column(
        children: [
          ClipPath(
           clipper: BottomClippertest(),
            child: Container(
              color: Colors.deepOrangeAccent,
              height: 200,
            ),
          )
        ],
      ),
    );
  }

我們這邊寫了ClipPath 來處理我們貝塞爾曲線的繪制 ClipPath 里面我們嵌套了一個(gè) Container 盒子組件設(shè)置高度200 寬度撐滿屏幕 然后我們來處理ClipPath 組件里面的 clipper 熟悉

class  BottomClippertest extends CustomClipper<Path>{
  @override
  Path getClip(Size size) {
    var path=Path();
    path.lineTo(0, 0); //第一個(gè)點(diǎn)
    path.lineTo(0, size.height-60);//第二個(gè)點(diǎn)
    var firstControlPoint=Offset(size.width/2, size.height);  //曲線開始點(diǎn)
    var firstendPoint=Offset(size.width, size.height-60); // 曲線結(jié)束點(diǎn)
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstendPoint.dx, firstendPoint.dy);
    path.lineTo(size.width, size.height-60); //第四個(gè)點(diǎn)
    path.lineTo(size.width,0);  // 第五個(gè)點(diǎn)
    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

我們這邊寫了一個(gè) BottomClippertest 類繼承與 CustomClipper 然后重寫了getClip 和 shouldReclip 方法 ,shouldReclip 方法我們返回 false 在 getClip 方法中我們創(chuàng)建 path對(duì)象

 var path=Path();

然后繪制貝塞爾曲線需要的 一些節(jié)點(diǎn) 如上圖話的5個(gè)點(diǎn)和 貝塞爾曲線的需要的開始點(diǎn)和結(jié)束點(diǎn) 最后我們返回一個(gè) path對(duì)象即可
完整代碼:

import 'package:flutter/material.dart';
/**
 *
 * 創(chuàng)建人:xuqing
 * 創(chuàng)建時(shí)間:2020年11月14日16:28:54
 * 類說明: 普通貝塞爾曲線
 *
 *
 */
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() {
    return _MyHomePageState();
  }
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }
  @override
  void dispose() {
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: Column(
        children: [
          ClipPath(
           clipper: BottomClippertest(),
            child: Container(
              color: Colors.deepOrangeAccent,
              height: 200,
            ),
          )
        ],
      ),
    );
  }
}
class  BottomClippertest extends CustomClipper<Path>{
  @override
  Path getClip(Size size) {
    var path=Path();
    path.lineTo(0, 0); //第一個(gè)點(diǎn)
    path.lineTo(0, size.height-60);//第二個(gè)點(diǎn)
    var firstControlPoint=Offset(size.width/2, size.height);  //曲線開始點(diǎn)
    var firstendPoint=Offset(size.width, size.height-60); // 曲線結(jié)束點(diǎn)
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstendPoint.dx, firstendPoint.dy);
    path.lineTo(size.width, size.height-60); //第四個(gè)點(diǎn)
    path.lineTo(size.width,0);  // 第五個(gè)點(diǎn)
    return path;
  }
  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

波浪形貝塞爾曲線實(shí)現(xiàn):

QQ截圖20201116114701.png
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: Column(
        children: [
          ClipPath(
            clipper: BottomClipper(),
            child: Container(
              color: Colors.blue,
              height: 200,
            ),
          )
        ],
      ),
    );
  }
}

我們很上面的普通的貝塞爾曲線一樣 我寫了一個(gè) `ClipPath 組件 里面嵌套一個(gè) Container 組件高度200 寬度撐滿屏幕 我們重點(diǎn)看一下 clipper 屬性的實(shí)現(xiàn):


class  BottomClipper extends CustomClipper<Path>{
  @override
  Path getClip(Size size) {
    var path=Path();
    path.lineTo(0, 0);
    path.lineTo(0, size.height-40);
    var firstControlPoint=Offset(size.width/4, size.height);
    var firstendPoint=Offset(size.width/2.25, size.height-30);
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstendPoint.dx, firstendPoint.dy);
    var  secondConttorPoint=Offset(size.width/4*3, size.height-90);
    var  secondendPoint=Offset(size.width, size.height-40);
    path.quadraticBezierTo(secondConttorPoint.dx, secondConttorPoint.dy,
        secondendPoint.dx, secondendPoint.dy);
    path.lineTo(size.width, size.height-40);
    path.lineTo(size.width,0);
    return path;
  }
  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

同上我們寫了一個(gè)BottomClipper 類繼承 CustomClipper 類 重寫getClip 方法和 shouldReclip ,shouldReclip 返回 false 重點(diǎn)是getClip 方法里面 我們創(chuàng)建 path對(duì)象

var path=Path();

這個(gè)波浪形的貝塞爾曲線我們有2個(gè)控制點(diǎn) 分別是在屏幕寬度1/4和屏幕寬度按3/4 處

 var firstControlPoint=Offset(size.width/4, size.height);  //第一個(gè)控制點(diǎn)起始點(diǎn)
    var firstendPoint=Offset(size.width/2.25, size.height-30);//第一個(gè)控制結(jié)束點(diǎn)
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstendPoint.dx, firstendPoint.dy);
    var  secondConttorPoint=Offset(size.width/4*3, size.height-90); // 第二個(gè)控制點(diǎn)起始點(diǎn)
    var  secondendPoint=Offset(size.width, size.height-40); // 第二個(gè)控制點(diǎn)結(jié)束點(diǎn)
    path.quadraticBezierTo(secondConttorPoint.dx, secondConttorPoint.dy,
        secondendPoint.dx, secondendPoint.dy);

其他的點(diǎn)和上面通普通貝塞爾曲線相同最后我們返回path 即可實(shí)現(xiàn)我們的波浪形貝塞爾曲線的繪制了
到此我們最基礎(chǔ)的貝塞爾曲線的繪制就講完了

最后總結(jié):

有時(shí)候我們?cè)诠ぷ髦行枰玫揭恍┣€背景的時(shí)候 我們就可以用到貝塞爾曲線繪制加上對(duì)應(yīng)顏色背景即可 這時(shí)候有同學(xué)就跳出來講 直接一張圖片就搞定了 但是我們加了圖片就會(huì)增加資源文件 也相對(duì)應(yīng)增加flutter項(xiàng)目打包成安裝包的體積,flutter里面提供好用的api供我們調(diào)用 我們只需要找到對(duì)應(yīng)節(jié)點(diǎn)然后返回路徑去繪制即可。以上的簡(jiǎn)單例子只是分享給同學(xué)們 ,同學(xué)們可以自己研究繪制出更多炫酷的曲線效果,我這邊就不展開講了。 最后希望我的文章能幫助到各位解決問題 ,以后我還會(huì)貢獻(xiàn)更多有用的代碼分享給大家。各位同學(xué)如果覺得文章還不錯(cuò) ,麻煩給關(guān)注和star,小弟在這里謝過啦

項(xiàng)目地址:

碼云 :https://gitee.com/qiuyu123/flutterbeziercurve

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容