canvas_models.dart (4072B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | import 'dart:ui'; import 'package:flutter/material.dart'; enum DragHandle { none, topLeft, topRight, bottomLeft, bottomRight, center } enum LayerType { sketch, image } class DrawingPoint { final Offset offset; final Paint paint; const DrawingPoint({required this.offset, required this.paint}); Map<String, dynamic> toMap() => {'dx': offset.dx, 'dy': offset.dy}; factory DrawingPoint.fromMap(Map<String, dynamic> map) { return DrawingPoint( offset: Offset(map['dx'] ?? 0, map['dy'] ?? 0), paint: Paint(), ); } } class DrawingPath { final List<DrawingPoint> points; final Color color; final double strokeWidth; final bool isEraser; DrawingPath({ required this.points, required this.color, required this.strokeWidth, required this.isEraser, }); Map<String, dynamic> toMap() { return { 'points': points.map((p) => p.toMap()).toList(), 'color': color.value, 'strokeWidth': strokeWidth, 'isEraser': isEraser, }; } factory DrawingPath.fromMap(Map<String, dynamic> map) { return DrawingPath( points: (map['points'] as List).map((p) => DrawingPoint.fromMap(p)).toList(), color: Color(map['color']), strokeWidth: (map['strokeWidth'] as num).toDouble(), isEraser: map['isEraser'] ?? false, ); } } // Layer Models abstract class CanvasLayer { final String id; final LayerType type; bool isVisible; CanvasLayer({required this.id, required this.type, this.isVisible = true}); Map<String, dynamic> toMap(); static CanvasLayer fromMap(Map<String, dynamic> map) { if (map['type'] == 'sketch') { return SketchLayer.fromMap(map); } else { return ImageLayer.fromMap(map); } } } class SketchLayer extends CanvasLayer { final List<DrawingPath> paths; final bool isMagicDraw; SketchLayer({ required String id, this.paths = const [], this.isMagicDraw = false, bool isVisible = true, }) : super(id: id, type: LayerType.sketch, isVisible: isVisible); @override Map<String, dynamic> toMap() { return { 'id': id, 'type': 'sketch', 'paths': paths.map((p) => p.toMap()).toList(), 'isMagicDraw': isMagicDraw, 'isVisible': isVisible, }; } factory SketchLayer.fromMap(Map<String, dynamic> map) { return SketchLayer( id: map['id'], paths: (map['paths'] as List).map((p) => DrawingPath.fromMap(p)).toList(), isMagicDraw: map['isMagicDraw'] ?? false, isVisible: map['isVisible'] ?? true, ); } } class ImageLayer extends CanvasLayer { final Map<String, dynamic> data; ImageLayer({required String id, required this.data, bool isVisible = true}) : super(id: id, type: LayerType.image, isVisible: isVisible); @override Map<String, dynamic> toMap() { final encodableData = Map<String, dynamic>.from(data); if (encodableData['position'] is Offset) { final pos = encodableData['position'] as Offset; encodableData['position'] = {'dx': pos.dx, 'dy': pos.dy}; } if (encodableData['size'] is Size) { final size = encodableData['size'] as Size; encodableData['size'] = {'width': size.width, 'height': size.height}; } return { 'id': id, 'type': 'image', 'data': encodableData, 'isVisible': isVisible, }; } factory ImageLayer.fromMap(Map<String, dynamic> map) { final data = Map<String, dynamic>.from(map['data']); // Restore Offset/Size objects if (data['position'] is Map) { data['position'] = Offset( (data['position']['dx'] as num).toDouble(), (data['position']['dy'] as num).toDouble(), ); } if (data['size'] is Map) { data['size'] = Size( (data['size']['width'] as num).toDouble(), (data['size']['height'] as num).toDouble(), ); } return ImageLayer( id: map['id'], data: data, isVisible: map['isVisible'] ?? true, ); } } class CanvasState { final List<CanvasLayer> layers; CanvasState(this.layers); } |