老孟导读: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. uniapp滚动监听元素

    鸽了这么久,一晃2个月过去了.自考+上班没时间记录. 前不久看到移动官网上的时间轴效果,看起来不错,我也来试着做一下. 需要元素滚动到视野内加载动画. 插件地址 https://ext.dcloud. ...

  2. puamap是什么意思

    artists map 定义格式:[puamap代号 名] 相关属性: 1.FIGHT 2.SAFE 安全区域 3.DARK 4.NEEDHOLE 配合mapinfo里 x,y -> x1,y1 ...

  3. 机器学习的hello world——MNIST

    MNIST:一个由60000行训练数据集和10000行的测试数据集(机器学习模型设计时必须有一个单独的数据集用于评估模型的性能)组成的数据集. 下载mnist的数据集后,将文件放入C:\Users\m ...

  4. 【Hadoop离线基础总结】MapReduce倒排索引建立

    MapReduce倒排索引建立 求某些单词在文章中出现多少次 有三个文档的内容,求hello,tom,jerry三个单词在其中各出现多少次 hello tom hello jerry hello to ...

  5. react中dangerouslySetInnerHTML使用

    在react中,通过富文本编辑器进行操作后的内容,会保留原有的标签样式,并不能正确展示. 在显示时,将内容写入__html对象中即可.具体如下: <div dangerouslySetInner ...

  6. hex文件格式总结

    hex文件格式总结 文章目录 hex文件格式总结 什么是hex文件? 文件格式 指令类型(Record type) 校验和 :04 02B0 00 92020008 AE :04 0000 05 08 ...

  7. 小程序如何动态修改标题navigationBarTitleText

    首先我们先设置标题.进入页面所在的json文件加入以下代码即可成功设置: "navigationBarTitleText": "我是标题啊!", 然后修改这个标 ...

  8. 初探numpy

    安装numpy 通过python pip安装numpy pip install numpy numpy ndarray对象 创建ndarray对象只需调用numpy的array函数即可 numpy.a ...

  9. HDU 2017 (水)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2017 题目大意:给你段字符串,求出字符串中含有数字字符的个数 解题思路: 字符串输入输出的基本应用:h ...

  10. 一、线程 & 线程池

    一.线程的介绍 1.1.概念 进程: 你的硬盘上有一个简单的程序,这个程序叫QQ.exe,这是一个程序,这个程序是一个静态的概念,它被扔在硬盘上也没人理他,但是当你双击它,弹出一个界面输入账号密码登录 ...