前言

在上一篇文章「手绘板的制作——手绘(1) 」中,我们完成了手绘的功能,这一篇我们在其基础上来讲讲重置与橡皮擦的功能实现。

在讲具体的功能实现前,我们需要先弄几个文本,用于笔刷、重置、橡皮擦的功能切换,同时把手绘板的功能抽取出来,放到 HandPaintedBoard 类中,大致代码如下,由于大多都是 UI 代码,可以直接初略看看即可,若需要自己实践再进行 copy。

void main() {runApp(const MyHomePage());
}class MyHomePage extends StatefulWidget {const MyHomePage({Key? key}) : super(key: key);@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {final PaintedBoardProvider _paintedBoardProvider = PaintedBoardProvider();   // <- 重点在这里@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(body: Container(color: Colors.white,child: SafeArea(child: Flex(direction: Axis.vertical,children: [SizedBox(height: 100,child: Flex(direction: Axis.horizontal,children: [Expanded(child: GestureDetector(onTap: () {print("点击了笔刷");},child: const Center(child: Text("笔刷"),),),),Expanded(child: GestureDetector(onTap: () {print("点击了重置");},child: const Center(child: Text("重置"),),),),Expanded(child: GestureDetector(onTap: () {print("点击了橡皮擦");},child: const Center(child: Text("橡皮擦"),),),),],),),Expanded(child: HandPaintedBoard(_paintedBoardProvider)),  // <- 重点在这里],),),),),);}
}
class HandPaintedBoard extends StatefulWidget {const HandPaintedBoard(this._paintedBoardProvider, {Key? key,}) : super(key: key);final PaintedBoardProvider _paintedBoardProvider;@override_HandPaintedBoardState createState() => _HandPaintedBoardState();
}class _HandPaintedBoardState extends State<HandPaintedBoard> {PaintedBoardProvider get _paintedBoardProvider =>widget._paintedBoardProvider;@overrideWidget build(BuildContext context) {return GestureDetector(onPanStart: (details) {_paintedBoardProvider.onStart(details);},onPanUpdate: (details) {_paintedBoardProvider.onUpdate(details);},onPanEnd: (details) {print("onPanDown:移动结束");},child: CustomPaint(painter: MyPainter(_paintedBoardProvider),size: Size.infinite,),);}
}

至于 stroke.dartpainted_board_provider.dartmy_painter.dart 在 「手绘板的制作——手绘(1) 」中都有,这里就不贴出了。

UI 效果:

然后我们点击三个按钮试试:

I/flutter: 点击了笔刷
I/flutter: 点击了重置
I/flutter: 点击了橡皮擦

准备工作完成,正文开始!

重置

重置功能其实就是将当前绘画的内容全部清空,而我们用于存储绘画数据的为 PaintedBoardProvider 中的 List<Stroke> _strokes,所以,我们只要将其清空,然后刷下页面即可。

PaintedBoardProvider 中添加以下方法:

  void clearBoard() {_strokes.clear();notifyListeners();}

然后在点击的地方调用:

                      Expanded(child: GestureDetector(onTap: () {print("点击了重置");_paintedBoardProvider.clearBoard();},child: const Center(child: Text("重置"),),),

ok,功能完成,就是这么简单,下一个。

橡皮擦

关于橡皮擦功能的实现,目前有两种方式:

  • 假清除效果,也就是把画笔颜色改为白色,或者说改为跟画布同一个颜色,然后这样绘画的时候,就会将原有的画笔绘画效果覆盖住,造成一种清除效果的假象。所以这里不建议这样使用,有兴趣的可以自己实现下。
  • 真清除效果,也就是把画笔颜色改为透明,然后用画笔进行绘画的时候,当画笔绘画的内容产生交接时,将其 blendMode 改为 clear,就可以把交接处直接清除。

下面我们来讲讲真清除效果。

    // 获取绘画数据进行绘画for (final stroke in paintedBoardProvider.strokes) {final paint = Paint()..strokeWidth = stroke.width..color = stroke.color..strokeCap = StrokeCap.round..style = PaintingStyle.stroke..blendMode = stroke.isClear ? BlendMode.clear : BlendMode.src;  //  <-  新增canvas.drawPath(stroke.path, paint);}

看看效果:

em…怎么变成黑色了?虽然说我们是直接在画布上绘画,即使是把背景清除了,也不应该是黑色,因为我也尝试过使用橙色背景的 Container 包裹住 CustomPaint,但是画出的颜色还是黑色。对此了解的大佬麻烦解答下。

至于解决办法我倒是了解,也就是使用 saveLayer。相当于我们在使用 Photoshop 的时候,新建一个透明蒙层,在新的蒙层上进行绘画,等绘画完成后,我们可以调用 restore 将该蒙层贴回画布中,重新在画布上进行绘制。大致的代码如下:

    canvas.saveLayer(Rect.fromLTWH(0, 0, size.width, size.height), Paint());// 获取绘画数据进行绘画for (final stroke in paintedBoardProvider.strokes) {final paint = Paint()..strokeWidth = stroke.width..color = stroke.color..strokeCap = StrokeCap.round..style = PaintingStyle.stroke..blendMode = stroke.isClear ? BlendMode.clear : BlendMode.src;  //  <-  新增canvas.drawPath(stroke.path, paint);}canvas.restore();

效果:

手绘板的制作——重置与橡皮擦(2)相关推荐

  1. 手绘板的制作——画布保存(6)

    「手绘板的制作--手绘(1)」 「手绘板的制作--重置与橡皮擦(2)」 「手绘板的制作--命令模式与撤销.重制(3)」 「手绘板的制作--画布缩放(4)」 「手绘板的制作--画布移动(5)」 前言 经 ...

  2. 手绘板的制作——画布移动(5)

    前言 在上文「手绘板的制作--画布缩放(4)」中,我们学会了画布的缩放,这节我们学习下画布的移动,毕竟放大的画布不能移动的话,那放大还有什么意义.=_= 手势检测 既然要移动,那当然需要检测手势,由于 ...

  3. 手绘板的制作——手绘(1)

    前言 通过上一篇文章「如何优雅地画一张图」我们已经知道如何在画布里面绘画一张图了,这次我准备开一个系列讲解下手绘板的制作,可能包含: 手绘 橡皮擦 撤销 重制 重置 图片导出 命令模式 等功能.具体等 ...

  4. 手绘板的制作——画布缩放(4)

    前言 在这一篇中,我们讲解下画布的缩放,也就是做一个根据手势缩放进行画布缩放的功能. 我们先来梳理下逻辑: 监听手势,当为一根手指的时候,就延续之前的操作,执行手绘操作,当操作为两根手指的时候,则执行 ...

  5. 手绘板的制作——命令模式与撤销、重制(3)

    前言 我们这篇来了解下撤销.重制的功能,其实也就是 undo 和 redo,在这里我们使用命令模式去设计,若对该模式不了解的话,可以考虑看下 「关于命令模式的误区,你知道了吗」. 其实对于命令模式,我 ...

  6. Android View与SurfaceView的手绘板制作

    最近学习了如何使用View与SurfaceView制作简单的手绘板,在此做个小结. 自定义VIew实现手绘板: 首先是使用View来实现手绘板: package com.app.superxlcr.m ...

  7. 手绘线条一直画不直_手绘板线条画不直怎么办?板绘画线诀窍分享

    在数位板画画和在纸上画画是有一定区别的,线条很难控制,手绘板线条画不直,那么如何在数位板上画出流畅线条?越是习惯手绘的朋友,那你可能就需要画更多的时间来适应数位板的画图方式,今天微课菌给大家分享一组板 ...

  8. 安卓开发-手绘板自定义绘画的保存,清空与恢复

    写这篇文章是因为代码中刚实现过这些功能,害怕自己之后会忘记,所以把整个方法写出来,方便自己日后复习用. 还是老样子,先上图: 1.首页 2.点击手绘板图片后跳出的窗口 3.用手指进行绘制 4.点击保存 ...

  9. java画图颜色_手绘板,多种颜色选择。我抄的《疯狂java讲义》的,包我乱导的,但代码能用。...

    [java]代码库import javax.swing.*; import java.awt.image.*; import java.awt.datatransfer.*; import javax ...

  10. 什么是数位板? 数位板,又名绘图板、绘画板、手绘板等等,是计算机输入设备的一种,通常是由一块板子和一支压感笔组成,它和手写板等作为非常规的输入产品相类似,都针对一定的使用群体。 与手写板所不同的是

    什么是数位板? 数位板,又名绘图板.绘画板.手绘板等等,是计算机输入设备的一种,通常是由一块板子和一支压感笔组成,它和手写板等作为非常规的输入产品相类似,都针对一定的使用群体. 与手写板所不同的是,数 ...

最新文章

  1. DrugBank:小分子数据信息挖掘
  2. swoole基础01
  3. 解决SerMyAdmin无法登陆的问题
  4. 网络服务器分为文件服务器通信服务器和,近代中国落后、贫困的根本原因是()...
  5. eof在c语言中表示什么_日语中的鍵为什么既能表示“钥匙”也能表示“锁”?...
  6. 【HNOI2017】礼物
  7. matlab寻找闭合,MatLab求取多个闭合区域的轮廓、面积和bbox
  8. ajax实时刷新处理
  9. Eclipse选择哪个版本
  10. git 查看、创建、删除 本地,远程 分支
  11. HDU1249 三角形【切割平面】
  12. 靠播放业务吃不饱?音乐流媒体纷纷“加电商”卖周边
  13. hadoop集群搭建(3)
  14. 简易交通灯设计——数电课设
  15. 【论文笔记】Poison Frogs! Targeted Clean-Label Poisoning Attacks on Neural Networks
  16. 虚拟内存与虚拟存储器的区别
  17. 稳压二极管稳压电路如何设计
  18. 在家也能逛家居商场!宜家推出VR购物应用
  19. MySql基本查询、连接查询、子查询、正则表达查询讲解
  20. 2021-2027中国18650锂电池市场现状及未来发展趋势

热门文章

  1. 人工蜂群算法求解货位优化问题
  2. java compile方法_Java中带有示例的模式compile()方法
  3. 如何将自己的网站发布在互联网上?(仅针对小白,大佬忽略)
  4. 162手写板合封芯片专用IC输出可达50V外围简单SOP8封装
  5. 火狐浏览器设置深色主题
  6. Unity5.1 新的网络引擎UNET(一) 概括1
  7. 【Designing ML Systems】第 6 章 :模型开发和离线评估
  8. APMServ中Apache启动失败解决方法大全
  9. 解锁视频编码的前世今生:流媒体产业的隐藏剧情
  10. DFD数据流图的基本要素及易错点详细介绍