Flutter 貝塞爾曲線實現案例
前言:
各位同學大家好,有段時間沒有給大家更新文章了,趁著今天有時間我們就給大家分享一個flutter的貝塞爾曲線的繪製的案例,希望能幫助到各位同學的學習和工作,那麼廢話不多說我們正式開始 。
準備工作 :
需要安裝flutter的開發環境:大家可以去看看之前的教程:
1 win系統flutter開發環境安裝教程:https://www.jianshu.com/p/152447bc8718
2 mac系統flutter開發環境安裝教程:https://www.jianshu.com/p/bad2c35b41e3
效果圖:
具體實現:
普通貝塞爾曲線
@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 裡面我們嵌套了一個 Container 盒子元件設定高度200 寬度撐滿螢幕 然後我們來處理ClipPath 元件裡面的 clipper 熟悉
class BottomClippertest extends CustomClipper<Path>{ @override Path getClip(Size size) { var path=Path(); path.lineTo(0, 0); //第一個點 path.lineTo(0, size.height-60);//第二個點 var firstControlPoint=Offset(size.width/2, size.height); //曲線開始點 var firstendPoint=Offset(size.width, size.height-60); // 曲線結束點 path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstendPoint.dx, firstendPoint.dy); path.lineTo(size.width, size.height-60); //第四個點 path.lineTo(size.width,0); // 第五個點 return path; } @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) { return false; } }
我們這邊寫了一個 BottomClippertest 類繼承與 CustomClipper 然後重寫了getClip 和 shouldReclip 方法 ,shouldReclip 方法我們返回 false 在 getClip 方法中我們建立 path物件
var path=Path();
然後繪製貝塞爾曲線需要的 一些節點 如上圖話的5個點和 貝塞爾曲線的需要的開始點和結束點 最後我們返回一個 path物件即可
完整程式碼:
import 'package:flutter/material.dart'; /** * * 建立人:xuqing * 建立時間: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); //第一個點 path.lineTo(0, size.height-60);//第二個點 var firstControlPoint=Offset(size.width/2, size.height); //曲線開始點 var firstendPoint=Offset(size.width, size.height-60); // 曲線結束點 path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstendPoint.dx, firstendPoint.dy); path.lineTo(size.width, size.height-60); //第四個點 path.lineTo(size.width,0); // 第五個點 return path; } @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) { return false; } }
波浪形貝塞爾曲線實現:
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Column(
children: [
ClipPath(
clipper: BottomClipper(),
child: Container(
color: Colors.blue,
height: 200,
),
)
],
),
);
}
}
我們很上面的普通的貝塞爾曲線一樣 我寫了一個 `ClipPath 元件 裡面巢狀一個 Container 元件高度200 寬度撐滿螢幕 我們重點看一下 clipper 屬性的實現:
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;
}
}
同上我們寫了一個BottomClipper 類繼承 CustomClipper 類 重寫getClip 方法和 shouldReclip ,shouldReclip 返回 false 重點是getClip 方法裡面 我們建立 path物件
var path=Path();
這個波浪形的貝塞爾曲線我們有2個控制點 分別是在螢幕寬度1/4和螢幕寬度按3/4 處
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 即可實現我們的波浪形貝塞爾曲線的繪製了
到此我們最基礎的貝塞爾曲線的繪製就講完了
最後總結:
有時候我們在工作中需要用到一些曲線背景的時候 我們就可以用到貝塞爾曲線繪製加上對應顏色背景即可 這時候有同學就跳出來講 直接一張圖片就搞定了 但是我們加了圖片就會增加資原始檔 也相對應增加flutter專案打包成安裝包的體積,flutter裡面提供好用的api供我們呼叫 我們只需要找到對應節點然後返回路徑去繪製即可。以上的簡單例子只是分享給同學們 ,同學們可以自己研究繪製出更多炫酷的曲線效果,我這邊就不展開講了。 最後希望我的文章能幫助到各位解決問題 ,以後我還會貢獻更多有用的程式碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這裡謝過啦 也可以加我個人QQ/微信(1693891473)
專案地址:
碼雲 :https://gitee.com/qiuyu123/flutterbeziercurve