老孟导读:CustomPaint可以称之为动画鼻祖,它可以实现任何酷炫的动画和效果。CustomPaint本身没有动画属性,仅仅是绘制属性,一般情况下,CustomPaint会和动画控制配合使用,达到理想的效果。

基本用法

CustomPaint的用法非常简单,如下:

CustomPaint(
painter: MyCustomPainter(),
)

MyCustomPainter定义如下:

class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {} @override
bool shouldRepaint(MyCustomPainter oldDelegate) {
return this != oldDelegate;
}
}

上面的MyCustomPainter为了看起来清晰,什么也没有做,通常情况下,在paint方法内绘制自定义的效果。shouldRepaint方法通常在当前实例和旧实例属性不一致时返回true。

paint通过canvas绘制,size为当前控件的大小,下面看看canvas的方法。

绘制点

Paint _paint = Paint()
..color = Colors.red
..strokeWidth = 3; @override
void paint(Canvas canvas, Size size) {
var points = [
Offset(0, 0),
Offset(size.width / 2, size.height / 2),
Offset(size.width, size.height),
];
canvas.drawPoints(PointMode.points, points, _paint);
}

PointMode有3种模式:

  • points:点
  • lines:将2个点绘制为线段,如果点的个数为奇数,最后一个点将会被忽略
  • polygon:将整个点绘制为一条线

绘制线

canvas.drawLine(Offset(0, 0),Offset(size.width, size.height), _paint);

绘制路径

Paint _paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 3; @override
void paint(Canvas canvas, Size size) {
print('size:$size');
var _path = Path()
..moveTo(0, 0)
..lineTo(size.width, 0)
..lineTo(size.width, size.height)
..close();
canvas.drawPath(_path, _paint);
}

这里注意Paint.style,还可以设置为PaintingStyle.fill,效果如下:

此时Path的路径不要在一条直线上,否则会看不到效果。

绘制各种形状

绘制圆形

canvas.drawCircle(Offset(size.width/2, size.height/2), 20, _paint);

绘制椭圆

canvas.drawOval(Rect.fromLTRB(0, 0, size.width, size.height/2), _paint);

如果给定的Rect为正方形,那么椭圆将会变为圆形。

绘制弧

canvas.drawArc(
Rect.fromLTRB(0, 0, size.width, size.height), 0, pi/2, true, _paint);

绘制圆角矩形

canvas.drawRRect(
RRect.fromLTRBR(0, 0, size.width, size.height, Radius.circular(10)), _paint)

canvas还有很多绘制函数,比如贝塞尔曲线、三次贝塞尔曲线、画布的反转等操作,这里不在一一介绍。

这些函数和Android的Canvas基本一样,如果你有Android基础,直接套用即可。

最后奉上一个绘制玫瑰的动画效果:

这个效果是不是很酷炫,我们看下绘制花骨朵代码:

///
/// 绘制花骨朵
///
_drawFlower(Canvas canvas, Size size) {
//将花变为红色
if (flowerPaths.length >= RoseData.flowerPoints.length) {
var path = Path();
for (int i = 0; i < flowerPaths.length; i++) {
if (i == 0) {
path.moveTo(flowerPaths[i].dx, flowerPaths[i].dy);
} else {
path.lineTo(flowerPaths[i].dx, flowerPaths[i].dy);
}
}
_paint.style = PaintingStyle.fill;
_paint.color = _flowerColor;
canvas.drawPath(path, _paint);
}
//绘制线
_paint.style = PaintingStyle.stroke;
_paint.color = _strokeColor;
//去掉最后2个点,最后2个点为了绘制红色
var points = flowerPaths.sublist(0, max(0, flowerPaths.length - 2));
canvas.drawPoints(PointMode.polygon, points, _paint);
}

花骨朵的绘制只通过canvas.drawPath就实现了,其实整个玫瑰花的绘制都是通过canvas.drawPath加上动画控制实现的。

CustomPaint可以实现任何你想要的动画的效果,比如绘画版就可以通过此控件实现。

获取完整代码方式扫码下方二维码回复:rose

交流

老孟Flutter博客地址(近200个控件用法):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

Flutter 动画鼻祖之CustomPaint的更多相关文章

  1. 转:Flutter动画二

    1. 介绍 本文会从代码层面去介绍Flutter动画,因此不会涉及到Flutter动画的具体使用. 1.1 Animation库 Flutter的animation库只依赖两个库,Dart库以及phy ...

  2. 转:Flutter动画一

    1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的An ...

  3. Flutter 动画详解(一)

    本文主要介绍了动画的原理相关概念,对其他平台的动画做了一个简要的梳理,并简要的介绍了Flutter动画的一些知识. 1. 动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才 ...

  4. 《Flutter 动画系列一》25种动画组件超全总结

    动画运行的原理 任何程序的动画原理都是一样的,即:视觉暂留,视觉暂留又叫视觉暂停,人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称&q ...

  5. 《Flutter 动画系列》组合动画

    老孟导读:在前面的文章中介绍了 <Flutter 动画系列>25种动画组件超全总结 http://laomengit.com/flutter/module/animated_1/ < ...

  6. Flutter 动画使用

    旋转动画  透明度变换动画  在Android中,可以通过View.animate()对视图进行动画处理,那在Flutter中怎样才能对Widget进行处理 在Flutter中,可以通过动画库给wid ...

  7. flutter 动画双指放大图片

    class GridAnimation extends StatefulWidget { @override State<StatefulWidget> createState() { r ...

  8. flutter 动画 practice

    import 'package:flutter/material.dart'; import 'dart:io'; import 'dart:async'; main() => runApp(M ...

  9. flutter 动画

    AnimatedCrossFade AnimatedCrossFade让俩个子widget 交替淡入淡出. class AnimatedCrossFade1 extends StatefulWidge ...

随机推荐

  1. 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁

    ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...

  2. matlab读取csv文件并显示

    传统的方式可以通过读取文件,然后处理字符串的方式对csv文件进行解析,在matlab中可以通过csvread函数读取csv文件,然后通过plot对数据进行显示,也可以对里面的函数进行分析: csv文件 ...

  3. 这一份MySQL书单,可以帮你搞定90%以上的面试题!

  4. [csu1508 地图的四着色]二分图染色

    抽象后的题意:给一个不超过30个点的图,A从中选不超过5个点涂红绿两种颜色,B用黑白两种颜色把剩下的涂完,任意一条边两端的颜色不同,求每种颜色至少用涂一次的方案数 思路:枚举A涂的点的集合,将原图分成 ...

  5. [hdu4599]期望DP

    思路:容易知道G(x)=6x,H(x)=6F(x).此题的关键是求出F(x)的通项,要求F(x)的通项,先建立递推式:F(x)=1/6 * (F(x-1)+1) + 5/6 * (F(x-1)+1+F ...

  6. 初识spring boot maven管理--属性文件配置

    在使用springboot的时候可以使用属性文件配置对属性值进行动态配置,官方文档原文如下: Spring Boot uses a very particular PropertySource ord ...

  7. 【SMB源码解析系列】——001.JumpEngine函数

    在SMB的源码中大概有不到20处看起来很奇怪的指令,它的格式是通过jsr指令调用一个名为JumpEngine的函数,其后并不是跟随某些后续的逻辑指令,而是通过.dw定义了一系列16位地址. 我们可以看 ...

  8. Dozer-对象属性映射工具类

    Dozer-对象属性映射工具类 工具类代码: import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; impo ...

  9. 黑马程序员_毕向东_Java基础视频教程——类型转换(随笔)

    类型转换 class Test{ public static void main(String[] args) { byte b = 3; // b = b + 2; /* Test.java:5: ...

  10. 读懂操作系统(x86)之堆栈帧(过程调用)

    前言 为进行基础回炉,接下来一段时间我将持续更新汇编和操作系统相关知识,希望通过屏蔽底层细节能让大家明白每节所阐述内容.当我们写下如下C代码时背后究竟发生了什么呢? #include <stdi ...