老孟导读: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. mui指南

    转自https://www.cnblogs.com/koleyang/p/5146623.html http://dev.dcloud.net.cn/mui/ui/index.html#mask ht ...

  2. 使用天祥TX-1C调试DS18B20温度传感器的收获

    翻查DS18B20的DataSheet编写操作函数,其过程遇到了不少坎,记下来备查. 对于单总线的DS18B20芯片,首先严格按照时序图写出正确的“写0”.“写1”和“读0.1”的基础函数,再以此写出 ...

  3. 假如用王者荣耀的方式学习webpack

    英雄介绍 崴博.派克诞生于遥远西方的勇士之地,拥有着高超的机械技艺,善于运用各种工具来实现一些看似不可能完成的事.游历王者大陆时机缘巧合遇到了年轻的墨子,与之成为好友.后协助大宗师墨子建造了大陆第一雄 ...

  4. 【FreeRTOS学习04】小白都能懂的 Queue Management 消息队列使用详解

    消息队列作为任务间同步扮演着必不可少的角色: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 xQUEUE 3 相关概念 3 ...

  5. Mysql 常用函数(14)- lower 函数

    Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html lower 的作用 将所有字符串更改为小写,然后返 ...

  6. 基于MySQL 的 SQL 优化总结

    文章首发于我的个人博客,欢迎访问.https://blog.itzhouq.cn/mysql1 基于MySQL 的 SQL 优化总结 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 ...

  7. tcp/ip 学习(一)

    TCP/IP协议是什么? TCP:Transmission Control Protocol  传输控制协议 IP:Internet Protocol  因特网协议 简单来说,TCP/IP协议就是一个 ...

  8. 转帖 支撑4.5亿活跃用户的WhatsApp架构概览

    http://www.csdn.net/article/2014-02-27/2818559-an-overview-at-whatsapp's-19b-architecture/2 写的很好,确实牛 ...

  9. Python list列表修改元素

    Python 提供了两种修改列表(list)元素的方法,你可以每次修改单个元素,也可以每次修改一组元素(多个). 修改单个元素 修改单个元素非常简单,直接对元素赋值即可.请看下面的例子: nums = ...

  10. js 简单有效判断日期有效性(含闰年)

    原文:https://zhidao.baidu.com/question/1701946584925153620.html 要想精确验证,最容易想到的方法就是通过月份判断日期是否合法(1~28/29/ ...