一、前言:
隨著技術(shù)的加速前進和市場千變?nèi)f化的需求,在開發(fā)過程會明顯的感覺到系統(tǒng)提供的基礎(chǔ)UI組件/控件滿足不了當(dāng)下的需求,特別是動畫效果,和一些圖表類的需求,找一些別人寫好的輪子,總感覺有差異,總覺得還差點什么,不能百分百的滿足自己的需求。由此說明需要了解掌握繪制的的本質(zhì),掌握繪制的能力,萬變不離其中,想怎么畫怎么畫,需求愛怎么出就怎么出。這里學(xué)習(xí)參考 https://juejin.cn/book/6844733827265331214
二、需求:學(xué)習(xí)繪制能力,記錄學(xué)習(xí)過程,其實就是學(xué)習(xí)API,學(xué)習(xí)一些思維邏輯
學(xué)習(xí)demo已上傳github,https://github.com/yj229201093/flutter_draw 一個持續(xù)的過程,學(xué)習(xí)一點記錄一點,demo中包含很多要點,每個要點一個包,每個包下面都有 main.dart ,切換不同的 main.dart 運行即可。
三、行動:
1、繪制的基本要素認識:紙、筆、形、色,就像吃飯需要手 筷子 碗之類的。
紙: Canvas 畫布對象
筆: Paint 畫筆對象
形: Path 路徑對象
色: Color 顏色對象
2、搭建繪話的舞臺
CustomPaint組件
CustomPaint 組件可以用來顯示繪制出的東西。需要傳入 CustomPainter 對象。
自定義 PaperPainter 類繼承 CustomPainter。 在其中的paint方法中可以拿到的畫布Canvas。
繪制一個圓
void main() {
WidgetsFlutterBinding.ensureInitialized(); // 確定初始化
SystemChrome.setPreferredOrientations(// 使設(shè)備橫屏顯示
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
SystemChrome.setEnabledSystemUIOverlays([]); // 全屏顯示
runApp(Paper());
}
///位置 p01/s01_pure/paper.dart
import 'package:flutter/material.dart';
class Paper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(),
),
);
}
}
/// 繼承 CustomPainter類
class PaperPainter extends CustomPainter {
@override // paint方法
void paint(Canvas canvas, Size size) {
// TODO: implement paint
/// 畫筆對象
final Paint paint = Paint();
/// 在畫布繪制圓,drawCircle方法是繪制圓,三個參數(shù):圓心<drawCircle>,半徑<10>, paint 畫筆
canvas.drawCircle(Offset(100, 100), 10, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
效果
在這里插入圖片描述
三、簡單認識繪制對象 API
[1]. 整體認識一下 [Canvas] 的繪制 API
[2]. 整體認識一下 [Paint] 對象可設(shè)置的屬性
[3]. 整體認識一下 [Path] 對象可執(zhí)行的操作
1、Canvas 方法 :
---->[畫布狀態(tài)]----
void save()
void saveLayer(Rect bounds, Paint paint)
void restore()
int getSaveCount()
---->[畫布變換]----
void skew(double sx, double sy)
void rotate(double radians)
void scale(double sx, [double sy])
void translate(double dx, double dy)
void transform(Float64List matrix4)
---->[畫布裁剪]----
void clipRect(Rect rect, { ClipOp clipOp = ClipOp.intersect, bool doAntiAlias = true })
void clipRRect(RRect rrect, {bool doAntiAlias = true})
void clipPath(Path path, {bool doAntiAlias = true})
---->[畫布繪制--點相關(guān)]----
void drawPoints(PointMode pointMode, List<Offset> points, Paint paint)
void drawRawPoints(PointMode pointMode, Float32List points, Paint paint)
void drawLine(Offset p1, Offset p2, Paint paint)
void drawVertices(Vertices vertices, BlendMode blendMode, Paint paint)
---->[畫布繪制--矩形相關(guān)]----
void drawRect(Rect rect, Paint paint)
void drawRRect(RRect rrect, Paint paint)
void drawDRRect(RRect outer, RRect inner, Paint paint)
---->[畫布繪制--類圓相關(guān)]----
void drawOval(Rect rect, Paint paint)
void drawCircle(Offset c, double radius, Paint paint)
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
---->[畫布繪制--圖片相關(guān)]----
void drawImage(Image image, Offset p, Paint paint)
void drawImageRect(Image image, Rect src, Rect dst, Paint paint)
void drawImageNine(Image image, Rect center, Rect dst, Paint paint)
void drawAtlas(Image atlas,List<RSTransform> transforms,List<Rect> rects,List<Color> colors,BlendMode blendMode,Rect cullRect,Paint paint)
void drawRawAtlas(Image atlas,Float32List rstTransforms,Float32List rects,Int32List colors,BlendMode blendMode,Rect cullRect,Paint paint)
---->[畫布繪制--文字]----
void drawParagraph(Paragraph paragraph, Offset offset)
---->[畫布繪制--其他]----
void drawColor(Color color, BlendMode blendMode)
void drawPath(Path path, Paint paint)
void drawPaint(Paint paint)
void drawShadow(Path path, Color color, double elevation, bool transparentOccluder)
void drawPicture(Picture picture)
2、 Paint(畫筆) 屬性
isAntiAlias(抗鋸齒) color(顏色) blendMode(混合模式) style(畫筆樣式)
strokeWidth(線寬) strokeCap(線帽類型) strokeJoin(線接類型) strokeMiterLimit(斜接限制)
maskFilter(遮罩濾鏡) shader(著色器) colorFilter(顏色濾鏡) imageFilter(圖片濾鏡)
invertColors(是否反色) filterQuality(濾鏡質(zhì)量)
3、Path 方法
---->[路徑絕對移動]----
void moveTo(double x, double y)
void lineTo(double x, double y)
void quadraticBezierTo(double x1, double y1, double x2, double y2)
void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3)
void conicTo(double x1, double y1, double x2, double y2, double w)
void arcTo(Rect rect, double startAngle, double sweepAngle, bool forceMoveTo)
void arcToPoint(Offset arcEnd, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true,})
---->[路徑相對移動]----
void relativeMoveTo(double dx, double dy)
void relativeLineTo(double dx, double dy)
void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2)
void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3)
void relativeConicTo(double x1, double y1, double x2, double y2, double w)
void relativeArcToPoint(Offset arcEndDelta, { Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true, })
---->[路徑添加]----
void addRect(Rect rect)
void addRRect(RRect rrect)
void addOval(Rect oval)
void addArc(Rect oval, double startAngle, double sweepAngle)
void addPolygon(List<Offset> points, bool close)
void addPath(Path path, Offset offset, {Float64List matrix4})
void extendWithPath(Path path, Offset offset, {Float64List matrix4})
---->[路徑操作]----
void close()
void reset()
bool contains(Offset point)
Path shift(Offset offset)
Path transform(Float64List matrix4)
Rect getBounds()
set fillType(PathFillType value)
static Path combine(PathOperation operation, Path path1, Path path2)
PathMetrics computeMetrics({bool forceClosed = false})
///位置 p02/s02_simple/paper.dart
import 'package:flutter/material.dart';
class Paper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(
painter: PaperPainter(),
),
);
}
}
class PaperPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
final Paint paint = Paint();
/// 畫筆設(shè)置
paint
..color = Colors.blue // 顏色 藍色
..strokeWidth = 4 // 線寬 4
..style = PaintingStyle.stroke; // 樣式
/// 繪制線 兩點 加 畫筆的設(shè)置
canvas.drawLine(Offset(0, 0), Offset(100, 100), paint);
Path path = Path(); // 路勁
path.moveTo(100, 100);
path.lineTo(200, 0);
/// 繪制路徑
canvas.drawPath(path, paint..color = Colors.red);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
效果:
在這里插入圖片描述
初認識,結(jié)束