controller.dart 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import 'dart:io';
  2. import 'dart:ui' as ui;
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:get/get.dart';
  6. import 'package:o2oa_all_platform/common/extension/date_extension.dart';
  7. import '../../../common/utils/index.dart';
  8. import 'index.dart';
  9. import 'widgets/hw_painter.dart';
  10. import 'widgets/hw_painter_data.dart';
  11. class HandwritingController extends GetxController {
  12. HandwritingController();
  13. final state = HandwritingState();
  14. final defaultPaintColor = Colors.black; //默认的画笔颜色
  15. final defaultPaintStokeWidth = 2.0; //默认的画笔宽度
  16. //TODO 画笔大小,颜色
  17. @override
  18. void onReady() {
  19. _setLandscape(); // 手写板 默认横屏
  20. super.onReady();
  21. }
  22. /// 在 [onDelete] 方法之前调用。
  23. @override
  24. void onClose() {
  25. _setPortrait();
  26. super.onClose();
  27. }
  28. /// 手写
  29. void paintByData(Offset? offset) {
  30. HWPainterData? data;
  31. if (offset != null) {
  32. data = HWPainterData(offset, defaultPaintColor, defaultPaintStokeWidth);
  33. }
  34. state.points.add(data);
  35. }
  36. /// 清空画布
  37. void refreshPainter() {
  38. state.points.clear();
  39. }
  40. /// 保存图片
  41. /// 并返回图片路径到 result 中
  42. Future<void> savePainterToImage(Size size) async {
  43. if (state.points.isEmpty) {
  44. Loading.showError("common_handwriting_msg_error_null_data".tr);
  45. return;
  46. }
  47. Loading.show();
  48. //画板保存成图片
  49. var image = await _rendered(size);
  50. var pngBytes = await image.toByteData(format: ui.ImageByteFormat.png);
  51. if (pngBytes == null) {
  52. Loading.showError("common_handwriting_msg_error_null_data".tr);
  53. return;
  54. }
  55. //图片临时存储
  56. final timeString = 'handwriting_${DateTime.now().millisecondsSinceEpoch}';
  57. var dir = await O2FilePathUtil.getTempFolderWithUrl(timeString);
  58. if (dir == null || dir.isEmpty) {
  59. OLogger.e('本地文件目录生成失败! url: $timeString');
  60. Loading.showError('下载失败!');
  61. return;
  62. }
  63. String filePath = '$dir/$timeString.png';
  64. File file = File(filePath);
  65. file.writeAsBytesSync(pngBytes.buffer.asInt8List());
  66. Loading.dismiss();
  67. // 返回文件路径
  68. Get.back(result: filePath);
  69. }
  70. /// 画布内容 渲染到 Image 中
  71. Future<ui.Image> _rendered(Size size) async {
  72. ui.PictureRecorder recorder = ui.PictureRecorder();
  73. Canvas canvas = Canvas(recorder);
  74. HWPainter painter = HWPainter(state.points);
  75. painter.paint(canvas, size);
  76. var image = await recorder
  77. .endRecording()
  78. .toImage(size.width.floor(), size.height.floor());
  79. return image;
  80. }
  81. // 设置横屏
  82. _setLandscape() {
  83. SystemChrome.setPreferredOrientations(
  84. [DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft]);
  85. if (Platform.isAndroid) {
  86. ///关闭状态栏,与底部虚拟操作按钮
  87. SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
  88. }
  89. }
  90. // 设置竖屏
  91. _setPortrait() {
  92. SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  93. if (Platform.isAndroid) {
  94. ///显示状态栏,与底部虚拟操作按钮
  95. SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
  96. overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
  97. }
  98. }
  99. }