Browse Source

支持加载初始绘制副本,支持多线同时触发绘制

gavin.chen 2 years ago
parent
commit
760167dd11

File diff suppressed because it is too large
+ 0 - 0
.flutter-plugins-dependencies


+ 1 - 1
lib/components/white_board/index.dart

@@ -2,4 +2,4 @@ library white_board;
 
 export './structure.dart';
 export './white_board.dart';
-export './color_util.dart';
+export 'utils.dart';

+ 26 - 0
lib/components/white_board/color_util.dart → lib/components/white_board/utils.dart

@@ -73,3 +73,29 @@ class ColorUtil {
     return p;
   }
 }
+
+class PointsUtil {
+  static String compressPointsList(List<List<double>> points) {
+    // print(points);
+    String result = '';
+    for (List<double> point in points) {
+      result +=
+          point[0].toStringAsFixed(4).replaceAll('0.', '').padRight(4, '0') +
+              point[1].toStringAsFixed(4).replaceAll('0.', '').padRight(4, '0');
+    }
+    return result;
+  }
+
+  static List<List<double>> decompressPointsList(String compressed) {
+    List<List<double>> result = [];
+    for (int i = 0; i < compressed.length; i += 8) {
+      String xString = compressed.substring(i, i + 4);
+      String yString = compressed.substring(i + 4, i + 8);
+      double x = double.parse(xString) / 10000;
+      double y = double.parse(yString) / 10000;
+      result.add([x, y]);
+    }
+    print(result);
+    return result;
+  }
+}

+ 71 - 20
lib/components/white_board/white_board.dart

@@ -1,7 +1,7 @@
 import 'dart:convert';
 
 import 'package:fis_common/event/event_type.dart';
-import 'package:fis_lib_business_components/components/white_board/color_util.dart';
+import 'package:fis_lib_business_components/components/white_board/utils.dart';
 import 'package:fis_lib_business_components/components/white_board/structure.dart';
 import 'package:fis_lib_business_components/components/white_board/white_board_painter.dart';
 import 'package:flutter/material.dart';
@@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
 class WhiteBoard extends StatefulWidget {
   const WhiteBoard({
     key,
+    required this.initData,
     required this.userId,
     required this.paintType,
     required this.sendData,
@@ -16,6 +17,9 @@ class WhiteBoard extends StatefulWidget {
     required this.onClearCanavs,
   });
 
+  /// 初始画板副本数据
+  final List<String> initData;
+
   /// 用户id
   final String userId;
 
@@ -49,15 +53,26 @@ class _WhiteBoardState extends State<WhiteBoard> {
   /// 固定的画笔粗细
   static const double strokeWidth = 3.0;
 
+  /// 异步绘制队列
+  List<String> _asyncDrawQueue = [];
+
+  /// 异步绘制锁
+  bool _asyncDrawLock = false;
+
   @override
   void initState() {
     super.initState();
     widget.onReceiveData.addListener((sender, data) {
-      _onReceiveData(data);
+      _onReceiveDrawData(data);
     });
     widget.onClearCanavs.addListener((sender, userId) {
       _clearUserLines(userId);
     });
+
+    /// 加载完后一帧绘制初始数据
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      _paintInitData();
+    });
   }
 
   @override
@@ -106,44 +121,80 @@ class _WhiteBoardState extends State<WhiteBoard> {
 
   /// 抬起时,发送数据
   void _onPanEnd(DragEndDetails details) {
-    _sentData();
+    _sentDrawAction();
     myPen.doneLine();
   }
 
-  /// 发送数据
-  void _sentData() {
-    List<List<double>> pathIdLists = [];
+  /// 绘制初始数据
+  void _paintInitData() {
+    for (int i = 0; i < widget.initData.length; i++) {
+      _onReceiveDrawDataImmediately(widget.initData[i]);
+    }
+  }
+
+  /// 发送绘制指令
+  void _sentDrawAction() {
+    List<List<double>> pointsList = [];
     for (int i = 0; i < myPen.activeLine.points.length; i++) {
-      pathIdLists.add(myPen.activeLine.points[i].toList());
+      pointsList.add(myPen.activeLine.points[i].toList());
     }
     widget.sendData(jsonEncode({
-      "action": "add",
-      "type": widget.paintType.index,
-      "userId": widget.userId,
-      "lineId": "",
-      "pathIdList": jsonEncode(pathIdLists),
+      "u_Id": widget.userId, // 用户id
+      "l_Id": "", // 线id
+      "points": PointsUtil.compressPointsList(pointsList),
     }));
   }
 
-  /// 接收数据
-  void _onReceiveData(String crossData) async {
-    var data = jsonDecode(crossData);
-    List<dynamic> pathIdList = jsonDecode(data["pathIdList"]);
+  /// 接收绘制数据【如果存在数据正在绘制,其他的加入绘制队列,等待当前绘制完成继续绘制】
+  void _onReceiveDrawData(String jsonData) async {
+    if (_asyncDrawLock) {
+      _asyncDrawQueue.add(jsonData);
+      return;
+    }
+    _asyncDrawLock = true;
+    var data = jsonDecode(jsonData);
+    List<dynamic> pointsList = PointsUtil.decompressPointsList(data["points"]);
     Line line = Line(
-      color: ColorUtil.generateColor(data["userId"]),
+      color: ColorUtil.generateColor(data["u_Id"]),
       strokeWidth: strokeWidth,
-      userId: data["userId"],
+      userId: data["u_Id"],
     );
 
     myPen.pushLine(line);
 
-    for (int i = 0; i < pathIdList.length; i++) {
+    for (int i = 0; i < pointsList.length; i++) {
       myPen.pushPoint(Point.fromList(
-        pathIdList[i],
+        pointsList[i],
       ));
       await Future.delayed(const Duration(milliseconds: 2));
     }
     myPen.doneLine();
+    _asyncDrawLock = false;
+
+    /// 判断如果队列存在数据,继续绘制
+    if (_asyncDrawQueue.isNotEmpty) {
+      _onReceiveDrawData(_asyncDrawQueue.removeAt(0));
+    }
+  }
+
+  /// 接收绘制数据立即绘制,无 Future.delayed
+  void _onReceiveDrawDataImmediately(String jsonData) {
+    var data = jsonDecode(jsonData);
+    List<dynamic> pointsList = PointsUtil.decompressPointsList(data["points"]);
+    Line line = Line(
+      color: ColorUtil.generateColor(data["u_Id"]),
+      strokeWidth: strokeWidth,
+      userId: data["u_Id"],
+    );
+
+    myPen.pushLine(line);
+
+    for (int i = 0; i < pointsList.length; i++) {
+      myPen.pushPoint(Point.fromList(
+        pointsList[i],
+      ));
+    }
+    myPen.doneLine();
   }
 
   void _clearUserLines(String userId) {

File diff suppressed because it is too large
+ 14 - 5
lib/main.dart


Some files were not shown because too many files changed in this diff