import 'dart:ui' as ui; import 'package:fis_measure/values/colors.dart'; import 'package:flutter/material.dart'; import 'package:path_drawing/path_drawing.dart'; extension MeasureCanvasExt on Canvas { static String? _fontFamily; /// 设置字体 static void setFontFamily(String? val) { _fontFamily = val; } /// 绘制文本 /// /// [text] 文本内容 /// /// [offset] 位置 /// /// [style] 文字样式 void drawText( String text, ui.Offset offset, { TextStyle? style, }) { var displayStyle = style; if (displayStyle != null) { if (displayStyle.fontFamily == null) { displayStyle = displayStyle.copyWith(fontFamily: _fontFamily); } } var textPainter = TextPainter( text: TextSpan( text: text, style: displayStyle, ), textAlign: ui.TextAlign.start, textDirection: TextDirection.ltr, ); textPainter.layout(); textPainter.paint(this, offset); } /// 绘制文本段落 /// /// [text] 文本内容 /// /// [offset] 位置 /// /// [width] 限制长度 /// /// [style] 文字样式 /// /// [maxLines] 最大行数 void drawTextParagraph( String text, ui.Offset offset, double width, { ui.TextStyle? style, int maxLines = 1, }) { var pb = ui.ParagraphBuilder( ui.ParagraphStyle( textAlign: TextAlign.left, textDirection: ui.TextDirection.ltr, maxLines: maxLines, ), ); if (style != null) { pb.pushStyle(style); } pb.addText(text); final paragraph = pb.build()..layout(ui.ParagraphConstraints(width: width)); drawParagraph(paragraph, offset); } /// 画虚线 /// /// [p1] 第一个点 /// /// [p2] 第二个点 /// /// [dashWidth] 虚线点长度 /// /// [spaceWidth] 虚线点间隔长度 /// /// [paint] 画笔 void drawDashLine( Offset p1, Offset p2, double dashWidth, double spaceWidth, Paint paint, ) { final path = Path() ..moveTo(p1.dx, p1.dy) ..lineTo(p2.dx, p2.dy); drawPath( dashPath( path, dashArray: CircularIntervalList([dashWidth, spaceWidth]), ), paint, ); } /// 画虚线框 /// /// [p1] 起始顶点 /// /// [p2] 结束顶点 /// /// [dashWidth] 虚线点长度 /// /// [spaceWidth] 虚线点间隔长度 /// /// [paint] 画笔 void drawDashRect( Offset p1, Offset p2, double dashWidth, double spaceWidth, Paint paint, ) { final path = Path() ..moveTo(p1.dx, p1.dy) ..lineTo(p2.dx, p1.dy) ..lineTo(p2.dx, p2.dy) ..lineTo(p1.dx, p2.dy) ..close(); drawPath( dashPath( path, dashArray: CircularIntervalList([dashWidth, spaceWidth]), ), paint, ); } /// 画点集连线 /// [points] 点集 /// [paint] 画笔 void drawPointsLine(List points, Paint paint) { final path = Path(); for (var i = 0; i < points.length; i++) { if (i == 0) { path.moveTo(points[i].dx, points[i].dy); } else { path.lineTo(points[i].dx, points[i].dy); } } drawPath(path, paint); } static final Paint _vertexPaint = Paint() ..strokeWidth = 1 ..style = PaintingStyle.stroke ..isAntiAlias = true; /// 画顶点 /// /// [offset] 位置 /// /// [size] 尺寸 /// /// [active] 是否活动 void drawVertex( Offset offset, double size, { bool active = false, }) { final radius = size / 2.0; double x = offset.dx, y = offset.dy; save(); final path = Path(); // top_left -> bottom_right path.moveTo(x - radius, y - radius); path.lineTo(x + radius, y + radius); // top_right -> bottom_left path.moveTo(x + radius, y - radius); path.lineTo(x - radius, y + radius); _vertexPaint.color = active ? MeasureColors.ActiveCaliper : MeasureColors.Primary; drawPath(path, _vertexPaint); restore(); } }