持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
signature | Flutter Package (flutter-io.cn)
译时版本:5.2.1
signature
提供性能优化的签名 Canvas ,可以设置自定义样式、边界和初始状态。 用 Fluter 原生实现,支持所有平台。
选择该插件的理由
在创建该插件之时,以下问题还没有可用的方案:
- 在多种设备上运行
- 可设置 Canvas 的边界
- 可使用提前保存的状态初始化
用法
要使用该插件,在 pubspec.yaml 中添加 signature 作为依赖。
示例
// 导入包
import 'package:signature/signature.dart';
// 初始化controller。它包含 签名的点阵、笔迹的粗细和画笔的颜色。
// 它可用于和组件交互。
final SignatureController _controller = SignatureController(
penStrokeWidth: 5,
penColor: Colors.red,
exportBackgroundColor: Colors.blue,
);
// 初始化。结果是一个组件,所以可以直接在 build 方法中使用。
var _signatureCanvas = Signature(
controller: _controller,
width: 300,
height: 300,
backgroundColor: Colors.lightBlueAccent,
);
// 清空 Canvas
_controller.clear();
// 导出字节为 PNG
// 导入的图片会限制在绘制区域
_controller.toPngBytes();
// isEmpty/isNotEmpty 可用于检查是否提供了签名
_controller.isNotEmpty; // 提供了签名时为 True
_controller.isEmpty; // 没有提供签名时为 True
// 导出点阵 (2D的点阵大体就是 Canvas 上看到的内容)
var exportedPoints = _controller.points;
// 导出点阵 可用于初始化上面的 Controller
final SignatureController _controller = SignatureController(points: exportedPoints);
使用手记
在使用该插件时,发现导出图片时感觉清晰度不够,也没深入研究原因。
然后自己定制了一下。
-
添加一个全局Key,不过 Flutter 不建议这么使用。
signature.dart:
/// 导出用全局 Key final GlobalKey keyRepaintBoundary; /// constructor const Signature({ required this.keyRepaintBoundary, required this.controller, Key? key, this.backgroundColor = Colors.grey, this.dynamicPressureSupported = false, this.width, this.height, }) : super(key: key); -
设置 RepaintBoundary 的 key 为上面的全局 Key。
signature.dart:
child: RepaintBoundary( key: widget.keyRepaintBoundary, child: CustomPaint( painter: _SignaturePainter(widget.controller), child: ConstrainedBox( constraints: BoxConstraints( minWidth: maxWidth, minHeight: maxHeight, maxWidth: maxWidth, maxHeight: maxHeight), ), ), )), -
导出图片的地方,这里是导出为 Base64 编码后的数据。
keyRepaintBoundary 是设定给 Signature 组件的 keyRepaintBoundary。
最后的 imgData 即是 Base64 编码后的数据。if(keyRepaintBoundary.currentContext != null) { final RenderRepaintBoundary boundary = keyRepaintBoundary.currentContext! .findRenderObject() as RenderRepaintBoundary; final img = await boundary.toImage(pixelRatio: window.devicePixelRatio); final ByteData? bytes = await (img.toByteData(format: ImageByteFormat.png)); if(bytes!=null) { final Uint8List pngBytes = bytes!.buffer.asUint8List(); final imgData = base64Encode(pngBytes); } }