Flutter开发进阶之Canvas

Flutter开发进阶之Canvas

在Flutter开发中Canvas作为一个绘制2D图形的工具,提供了一系列绘图方法,可以用来绘制各种形状、线条、文本和图像等;
Canvas对象是作为CustomPainter的子组件进行构建的;

void paint(Canvas canvas, Size size);

Flutter开发

一、绘制的保存和恢复

Canvas通过使用以下方法调用原生层(C++)的绘图操作;

factory Canvas(PictureRecorder recorder, [ Rect? cullRect ]) = _NativeCanvas;

通过以下方法保存上下文和恢复;

void save();
void saveLayer(Rect? bounds, Paint paint);

void restore();
void restoreToCount(int count);
/// 保存数量
int getSaveCount();

二、绘制的变换

添加平移变换,分别在x轴和轴上;

void translate(double dx, double dy);

添加对应轴的缩放变换,若不指定sy则x轴和y轴都等比例缩放sx;

void scale(double sx, [double? sy]);

根据radians的弧度进行旋转变换;

void rotate(double radians);

相对原始角度对应的百分比倾斜变换;

void skew(double sx, double sy);

变换4x4矩阵;

void transform(Float64List matrix4);

变换的获取;

Float64List getTransform();

三、绘制的渲染流水线

还可以按指定规则进行裁剪;

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});

/// 获取裁剪的边界
Rect getLocalClipBounds();
Rect getDestinationClipBounds();

通过以下API进行形状图元的组合、着色;

/// 着色
void drawColor(Color color, BlendMode blendMode);
/// 通过画笔进行点对点划线
void drawLine(Offset p1, Offset p2, Paint paint);
/// 画笔填充
void drawPaint(Paint paint);
/// 绘制矩形
void drawRect(Rect rect, Paint paint);
/// 绘制圆角矩形
void drawRRect(RRect rrect, Paint paint);
/// 绘制两个圆角矩形之差,填充或描边由画笔决定
void drawDRRect(RRect outer, RRect inner, Paint paint);
/// 绘制椭圆
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);
/// 根据path绘制,一般是组合图形
void drawPath(Path path, Paint paint);
/// 给定位置绘制图片
void drawImage(Image image, Offset offset, Paint paint);
void drawImageRect(Image image, Rect src, Rect dst, Paint paint);
/// 图像分割成3x3绘制
void drawImageNine(Image image, Rect center, Rect dst, Paint paint);
/// 绘制图片
void drawPicture(Picture picture);
/// 给定位置的文本绘制
void drawParagraph(Paragraph paragraph, Offset offset);
/// 绘制点序列
void drawPoints(PointMode pointMode, List<Offset> points, Paint paint);
void drawRawPoints(PointMode pointMode, Float32List points, Paint paint);
/// 绘制顶点
void drawVertices(Vertices vertices, BlendMode blendMode, 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 drawShadow(Path path, Color color, double elevation, bool transparentOccluder);

四、绘制的路径

Canvas使用Path来描述描述2D图形路径,路径可以是线段、二次贝塞尔曲线、三次贝塞尔曲线等,这些都可以组合在一起形成一个复杂的图形;
Path可以通过以下的方法来调用原生层的操作;

factory Path() = _NativePath;

factory Path.from(Path source) {
    final _NativePath clonedPath = _NativePath._();
    (source as _NativePath)._clone(clonedPath);
    return clonedPath;
  }

通过以下方法决定如何计算路径内部;

PathFillType get fillType;
set fillType(PathFillType value);

以下从点开始的路径;

/// 点的移动从开始到重新开始
void moveTo(double x, double y);
void relativeMoveTo(double dx, double dy);

/// 直线的连线到重新连线
void lineTo(double x, double y);
void relativeLineTo(double dx, double dy);

/// 贝塞尔曲线
void quadraticBezierTo(double x1, double y1, double x2, double y2);
void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2);

/// 三次贝塞尔
void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3);
void relativeCubicTo(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 relativeConicTo(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 relativeArcToPoint(
    Offset arcEndDelta, {
    Radius radius = Radius.zero,
    double rotation = 0.0,
    bool largeArc = false,
    bool clockwise = true,
  });

以下直接给定图形的路径;

/// 矩形
void addRect(Rect rect);
/// 椭圆
void addOval(Rect oval);
/// 圆弧
void addArc(Rect oval, double startAngle, double sweepAngle);
/// 线段
void addPolygon(List<Offset> points, bool close);
/// 圆角
void addRRect(RRect rrect);

以下是路径的组合运算;

/// 添加路径
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();

/// 对路径进行组合
static Path combine(PathOperation operation, Path path1, Path path2) {
    final _NativePath path = _NativePath();
    if (path._op(path1 as _NativePath, path2 as _NativePath, operation.index)) {
      return path;
    }
    throw StateError('Path.combine() failed.  This may be due an invalid path; in particular, check for NaN values.');
  }
/// 多部分的路径轮廓属性,一个Path通常有0到多个轮廓线组成
PathMetrics computeMetrics({bool forceClosed = false});

五、绘制的画笔

Canvas使用Paint描述如何绘制图形,例如颜色、样式、混合模式等,以上我称之为画笔;
isAntiAlias:抗锯齿;
color:填充的颜色;
blendMode:图形混合时合成的模式;
style:是否绘制形状的内部,形状的边缘,或两者;
strokeWidth:线的宽度;
strokeCap:在绘制的线的末端放置的结束类型;
strokeJoin:连接点的类型;
strokeMiterLimit:斜接长度限制;
maskFilter:蒙版滤镜;
filterQuality:控制采样位图时使用的性能和质量权衡;
shader:形状着色器;
colorFilter:颜色滤镜;
imageFilter:图像滤镜;
invertColors:颜色反转。

以上时Flutter中Canvas绘图部分,具体的应用在实际开发中可能是地图线路绘制、AI图像转换、动画绘制等,如需深入还需了解计算机的渲染机制

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin写代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值