老孟导读: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. Pycharm修改HTML模板

  2. django 整理数据库文档时,从mysql导出的表中没有注释的解决方案

    公司要将Django项目重构成Java项目,也就有了整理数据库文档的经历....... 由于django从model迁移时没有将注释(也就是模型类中的verbose_name)写进mysql的表中,导 ...

  3. Spring Boot学习 之 Spring Boot Actuator(一)

    Spring Boot版本:2.1.4.RELEASE 启用: spring-boot-actuator模块提供了一系列的用于监控的端点.最简单的开启这个功能的方法就是,在pom文件中添加如下的依赖. ...

  4. 王颖奇 201771010129《面向对象程序设计(java)》第六周学习总结

    实验六 继承定义与使用 实验时间 2018-9-28 1.目的与要求 理论部分: 继承(inheritance): 继承的特点:具有结构层次:子类继承了父类的域和方法. 主要内容: (1)类.子类.超 ...

  5. STM32 外部中断详解(原理+配置代码)

    本文介绍了STM32基于标准外设库的外部中断配置,以及基于参考手册如何更加寄存器配置外部中断 文章目录 1 前言 2 STM32的外部中断 3 中断服务函数的映射关系 4 外部中断的配置 5 寄存器的 ...

  6. [工具]微软的学习平台Microsoft Learn很好用,推荐一下

    1. 什么是Microsoft Learn Microsoft Learn是微软这两年大力推广的全新学习平台,可提供 Microsoft 产品交互式学习体验.基本上无需登录即可使用,但登录后可以使用更 ...

  7. CF#358 D. Alyona and Strings DP

    D. Alyona and Strings 题意 给出两个字符串s,t,让找出最长的k个在s,t不相交的公共子串. 思路 看了好几个题解才搞懂. 代码中有注释 代码 #include<bits/ ...

  8. 设计模式GOF23之工厂模式01

    简单工厂模式和工厂方法模式 工厂模式核心:分工 简单工厂模式不符合OCP(Open-Closed Princinple)原则,扩展时需要更改原代码 工厂方法模式增加了类复杂度代码复杂度等,所以一般使用 ...

  9. Elasticsearch系列---几个高级功能

    概要 本篇主要介绍一下搜索模板.映射模板.高亮搜索和地理位置的简单玩法. 标准搜索模板 搜索模板search tempalte高级功能之一,可以将我们的一些搜索进行模板化,使用现有模板时传入指定的参数 ...

  10. Spring Boot 之 Spring Batch 批处理实践

    实践内容 从 MariaDB 一张表内读 10 万条记录,经处理后写到 MongoDB . 具体实现 1.新建 Spring Boot 应用,依赖如下: <!-- Web 应用 --> & ...