mirror of
https://github.com/NaserElziadna/doddle.git
synced 2026-03-13 07:41:06 +08:00
changes
This commit is contained in:
@@ -138,7 +138,7 @@ class CanvasNotifier extends _$CanvasNotifier {
|
||||
Future<ui.Image> canvasToImage(GlobalKey globalKey) async {
|
||||
final boundary =
|
||||
globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
|
||||
return await boundary.toImage();
|
||||
return await boundary.toImage(pixelRatio:5);
|
||||
}
|
||||
|
||||
Future<void> saveToGallery(GlobalKey globalKey) async {
|
||||
|
||||
@@ -1,33 +1,65 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:doddle/domain/models/effects/pen_effect.dart';
|
||||
import 'package:doddle/domain/models/point.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RainbowStroke {
|
||||
final Offset position;
|
||||
final Color color;
|
||||
final double size;
|
||||
|
||||
RainbowStroke({
|
||||
required this.position,
|
||||
required this.color,
|
||||
required this.size,
|
||||
});
|
||||
}
|
||||
|
||||
class NormalWithShaderEffect extends PenEffect {
|
||||
final List<RainbowStroke> strokes = [];
|
||||
int colorIndex = 0;
|
||||
|
||||
static const List<Color> rainbowColors = [
|
||||
Color.fromARGB(255, 255, 0, 0), // Red
|
||||
Color.fromARGB(255, 255, 127, 0), // Orange
|
||||
Color.fromARGB(255, 255, 255, 0), // Yellow
|
||||
Color.fromARGB(255, 0, 255, 0), // Green
|
||||
Color.fromARGB(255, 0, 0, 255), // Blue
|
||||
Color.fromARGB(255, 75, 0, 130), // Indigo
|
||||
Color.fromARGB(255, 148, 0, 211), // Violet
|
||||
];
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Path path, Paint paint) {
|
||||
canvas.drawPath(
|
||||
path,
|
||||
Paint()
|
||||
..shader = sweepShader
|
||||
..strokeJoin = StrokeJoin.round
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = drawController.penSize!,
|
||||
);
|
||||
for (var stroke in strokes) {
|
||||
final positions = getSymmetricalPositions(stroke.position);
|
||||
canvas.drawPoints(PointMode.lines, positions,
|
||||
Paint()
|
||||
..color = stroke.color
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = stroke.size
|
||||
..strokeCap = StrokeCap.round
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static final SweepGradient colorWheelGradient = SweepGradient(
|
||||
center: Alignment.bottomRight,
|
||||
colors: [
|
||||
Color.fromARGB(255, 255, 0, 0),
|
||||
Color.fromARGB(255, 255, 255, 0),
|
||||
Color.fromARGB(255, 0, 255, 0),
|
||||
Color.fromARGB(255, 0, 255, 255),
|
||||
Color.fromARGB(255, 0, 0, 255),
|
||||
Color.fromARGB(255, 255, 0, 255),
|
||||
Color.fromARGB(255, 255, 0, 0),
|
||||
]);
|
||||
// If we create a shader from the above SweepGraident, we get
|
||||
// a crash on web, but only on web.
|
||||
static final Shader sweepShader =
|
||||
colorWheelGradient.createShader(const Rect.fromLTWH(0, 0, 100, 10));
|
||||
@override
|
||||
void onPointAdd(Point point) {
|
||||
if (point.offset == null) return;
|
||||
|
||||
strokes.add(RainbowStroke(
|
||||
position: point.offset!,
|
||||
color: rainbowColors[colorIndex],
|
||||
size: drawController.penSize ?? 2.0,
|
||||
));
|
||||
|
||||
colorIndex = (colorIndex + 1) % rainbowColors.length;
|
||||
}
|
||||
|
||||
@override
|
||||
void onPointEnd() {
|
||||
colorIndex = 0;
|
||||
strokes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,14 +171,22 @@ class BrushConfigs {
|
||||
maxValue: 72.0,
|
||||
icon: Icons.format_size,
|
||||
),
|
||||
'spacing': BrushSettingConfig(
|
||||
label: 'Spacing',
|
||||
'wordSpacing': BrushSettingConfig(
|
||||
label: 'Word Spacing',
|
||||
type: SettingType.slider,
|
||||
defaultValue: 50.0,
|
||||
minValue: 10.0,
|
||||
maxValue: 200.0,
|
||||
icon: Icons.space_bar,
|
||||
),
|
||||
'letterSpacing': BrushSettingConfig(
|
||||
label: 'Letter Spacing',
|
||||
type: SettingType.slider,
|
||||
defaultValue: 0.0,
|
||||
minValue: -50.0,
|
||||
maxValue: 50.0,
|
||||
icon: Icons.space_bar,
|
||||
),
|
||||
'randomRotation': BrushSettingConfig(
|
||||
label: 'Random Rotation',
|
||||
type: SettingType.toggle,
|
||||
|
||||
@@ -13,7 +13,8 @@ class TextEffect extends PenEffect {
|
||||
String get text => settings.getValue('text') ?? 'Hello';
|
||||
double get fontSize => settings.getValue('fontSize') ?? 20.0;
|
||||
bool get randomRotation => settings.getValue('randomRotation') ?? false;
|
||||
double get spacing => settings.getValue('spacing') ?? 50.0;
|
||||
double get wordSpacing => settings.getValue('wordSpacing') ?? 0.0;
|
||||
double get letterSpacing => settings.getValue('letterSpacing') ?? 0.0;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Path path, Paint paint) {
|
||||
@@ -25,6 +26,8 @@ class TextEffect extends PenEffect {
|
||||
style: TextStyle(
|
||||
color: drawController.currentColor,
|
||||
fontSize: fontSize,
|
||||
wordSpacing: wordSpacing,
|
||||
letterSpacing: letterSpacing,
|
||||
),
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:doddle/core/theme/app_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -23,7 +24,8 @@ Future<void> initializeApp() async {
|
||||
|
||||
void main() async {
|
||||
await initializeApp();
|
||||
|
||||
//dont allow rotation
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
runApp(
|
||||
const ProviderScope(
|
||||
child: MyApp(),
|
||||
|
||||
@@ -117,6 +117,13 @@ class BrushSettingsPanel extends ConsumerWidget {
|
||||
),
|
||||
);
|
||||
case SettingType.text:
|
||||
// Create a persistent TextEditingController to maintain state
|
||||
final controller = TextEditingController(text: currentValue);
|
||||
// Maintain cursor position
|
||||
controller.selection = TextSelection.fromPosition(
|
||||
TextPosition(offset: controller.text.length)
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
@@ -133,7 +140,7 @@ class BrushSettingsPanel extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: TextEditingController(text: currentValue),
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
@@ -155,7 +162,7 @@ class BrushSettingsPanel extends ConsumerWidget {
|
||||
return Center(
|
||||
child: TextButton.icon(
|
||||
icon: const Icon(Icons.restart_alt),
|
||||
label: const Text('Reset to Default'),
|
||||
label: const Text('Reset Brush Settings to Default'),
|
||||
onPressed: () {
|
||||
ref.read(brushSettingsProvider(penTool).notifier).resetToDefault();
|
||||
},
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CanvasSize {
|
||||
final String name;
|
||||
final Size size;
|
||||
|
||||
const CanvasSize({
|
||||
required this.name,
|
||||
required this.size,
|
||||
});
|
||||
}
|
||||
|
||||
class CanvasSizeDialog extends StatelessWidget {
|
||||
CanvasSizeDialog({Key? key}) : super(key: key);
|
||||
|
||||
final List<CanvasSize> canvasSizes = [
|
||||
CanvasSize(name: 'Small (1080x1080)', size: const Size(1080, 1080)),
|
||||
CanvasSize(name: 'Medium (1920x1080)', size: const Size(1920, 1080)),
|
||||
CanvasSize(name: 'Large (2560x1440)', size: const Size(2560, 1440)),
|
||||
CanvasSize(name: 'Custom', size: Size.zero),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Select Canvas Size'),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: canvasSizes.map((size) {
|
||||
return ListTile(
|
||||
title: Text(size.name),
|
||||
onTap: () {
|
||||
if (size.name == 'Custom') {
|
||||
_showCustomSizeDialog(context);
|
||||
} else {
|
||||
Navigator.of(context).pop(size.size);
|
||||
}
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCustomSizeDialog(BuildContext context) {
|
||||
final widthController = TextEditingController();
|
||||
final heightController = TextEditingController();
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Custom Size'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TextField(
|
||||
controller: widthController,
|
||||
decoration: const InputDecoration(labelText: 'Width'),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
TextField(
|
||||
controller: heightController,
|
||||
decoration: const InputDecoration(labelText: 'Height'),
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final width = double.tryParse(widthController.text);
|
||||
final height = double.tryParse(heightController.text);
|
||||
if (width != null && height != null) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(Size(width, height));
|
||||
}
|
||||
},
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
|
||||
class Popover extends StatelessWidget {
|
||||
class Popover extends StatefulWidget {
|
||||
const Popover({
|
||||
Key? key,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
}): super(key: key);
|
||||
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
State<Popover> createState() => _PopoverState();
|
||||
}
|
||||
|
||||
class _PopoverState extends State<Popover> with SingleTickerProviderStateMixin {
|
||||
Widget _buildHandle(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
FractionallySizedBox(
|
||||
widthFactor: 0.25,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 12.0,
|
||||
),
|
||||
child: Container(
|
||||
height: 5.0,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.dividerColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(2.5)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
@@ -15,33 +49,23 @@ class Popover extends StatelessWidget {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(16.0),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: 90.w,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.cardColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [_buildHandle(context), if (child != null) child!],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHandle(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return FractionallySizedBox(
|
||||
widthFactor: 0.25,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 12.0,
|
||||
),
|
||||
child: Container(
|
||||
height: 5.0,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.dividerColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(2.5)),
|
||||
children: [
|
||||
_buildHandle(context),
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ class ToolsWidget extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Container(
|
||||
height: MediaQuery.of(context).size.height * .1,
|
||||
color: Colors.purple[800],
|
||||
color: Colors.purple[600],
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_buildToolButton(
|
||||
context,
|
||||
@@ -41,16 +41,20 @@ class ToolsWidget extends ConsumerWidget {
|
||||
orElse: () => symmetryLines.first,
|
||||
);
|
||||
|
||||
return _buildToolButton(
|
||||
context,
|
||||
icon: Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
children: [
|
||||
Assets.svg.symmetricalLineBg.svg(width: 80),
|
||||
selectedLine.picture,
|
||||
],
|
||||
return SizedBox(
|
||||
width: 80,
|
||||
height: 80,
|
||||
child: _buildToolButton(
|
||||
context,
|
||||
icon: Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
children: [
|
||||
Assets.svg.symmetricalLineBg.svg(width: 80),
|
||||
selectedLine.picture,
|
||||
],
|
||||
),
|
||||
toolType: ToolType.symmyrticllLine,
|
||||
),
|
||||
toolType: ToolType.symmyrticllLine,
|
||||
);
|
||||
}
|
||||
),
|
||||
@@ -69,7 +73,7 @@ class ToolsWidget extends ConsumerWidget {
|
||||
context,
|
||||
icon: const Icon(
|
||||
Icons.settings,
|
||||
size: 30,
|
||||
size: 80,
|
||||
color: Colors.white,
|
||||
),
|
||||
toolType: ToolType.canvasSettings,
|
||||
@@ -86,11 +90,7 @@ class ToolsWidget extends ConsumerWidget {
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (toolType == ToolType.brushs) {
|
||||
_showBrushSettings(context);
|
||||
} else {
|
||||
_showToolSettings(context, toolType);
|
||||
}
|
||||
_showToolSettings(context, toolType);
|
||||
},
|
||||
child: icon,
|
||||
);
|
||||
@@ -107,8 +107,9 @@ class ToolsWidget extends ConsumerWidget {
|
||||
|
||||
void _showToolSettings(BuildContext context, ToolType toolType) {
|
||||
showModalBottomSheet<void>(
|
||||
backgroundColor: Colors.transparent,
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return Popover(
|
||||
child: _buildToolContent(toolType),
|
||||
@@ -117,24 +118,6 @@ class ToolsWidget extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _showBrushSettings(BuildContext context) {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return const SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BrushToolGrid(),
|
||||
Divider(),
|
||||
BrushSettingsPanel(),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildToolContent(ToolType toolType) {
|
||||
switch (toolType) {
|
||||
case ToolType.brushs:
|
||||
@@ -144,7 +127,15 @@ class ToolsWidget extends ConsumerWidget {
|
||||
case ToolType.symmyrticllLine:
|
||||
return const SymmetryToolGrid();
|
||||
case ToolType.canvasSettings:
|
||||
return const CanvasSettingsToolGrid();
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
CanvasSettingsToolGrid(),
|
||||
Divider(),
|
||||
BrushSettingsPanel(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:doddle/application/providers/brush_settings_provider.dart';
|
||||
import 'package:doddle/application/providers/canvas/canvas_provider.dart';
|
||||
import 'package:doddle/domain/models/effects/pen_effect.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -17,32 +18,76 @@ class BrushPreviewPainter extends CustomPainter {
|
||||
final center = Offset(size.width / 2, size.height / 2);
|
||||
canvas.translate(center.dx, center.dy);
|
||||
|
||||
// Create a wavy line for preview
|
||||
final points = _generatePreviewPoints(size);
|
||||
final controller = DrawController(
|
||||
points: points,
|
||||
penTool: ref.read(canvasNotifierProvider).penTool,
|
||||
penSize: ref.read(canvasNotifierProvider).penSize,
|
||||
currentColor: ref.read(canvasNotifierProvider).currentColor,
|
||||
effects: ref.read(canvasNotifierProvider).effects,
|
||||
);
|
||||
|
||||
final effect = controller.effects[controller.penTool];
|
||||
final currentPenTool = ref.read(canvasNotifierProvider).penTool;
|
||||
|
||||
if (effect != null) {
|
||||
Path path = Path();
|
||||
Paint paint = Paint()
|
||||
..strokeCap = StrokeCap.round
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2.0;
|
||||
// Special handling for text brush preview
|
||||
if (currentPenTool == PenTool.textPen) {
|
||||
_drawTextPreview(canvas, size);
|
||||
} else {
|
||||
// Original wave preview for other brushes
|
||||
final points = _generatePreviewPoints(size);
|
||||
final controller = DrawController(
|
||||
points: points,
|
||||
penTool: currentPenTool,
|
||||
penSize: ref.read(canvasNotifierProvider).penSize,
|
||||
currentColor: ref.read(canvasNotifierProvider).currentColor,
|
||||
effects: ref.read(canvasNotifierProvider).effects,
|
||||
);
|
||||
|
||||
_drawPreviewPoints(canvas, path, paint, effect, points);
|
||||
effect.paint(canvas, path, paint);
|
||||
final effect = controller.effects[controller.penTool];
|
||||
|
||||
if (effect != null) {
|
||||
Path path = Path();
|
||||
Paint paint = Paint()
|
||||
..strokeCap = StrokeCap.round
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = controller.penSize ?? 2.0;
|
||||
|
||||
_drawPreviewPoints(canvas, path, paint, effect, points);
|
||||
effect.paint(canvas, path, paint);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void _drawTextPreview(Canvas canvas, Size size) {
|
||||
final settings = ref.read(brushSettingsProvider(PenTool.textPen));
|
||||
final text = settings.getValue('text') ?? 'Hello';
|
||||
final fontSize = settings.getValue('fontSize') ?? 20.0;
|
||||
final color = ref.read(canvasNotifierProvider).currentColor;
|
||||
|
||||
final textPainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: TextStyle(
|
||||
color: color,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
);
|
||||
textPainter.layout();
|
||||
|
||||
// Draw multiple instances of text along a curved path
|
||||
for (double x = -size.width/3; x <= size.width/3; x += 50) {
|
||||
final y = math.sin(x * 0.1) * 20;
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
|
||||
// Add slight rotation for visual interest
|
||||
canvas.rotate(math.sin(x * 0.05) * 0.3);
|
||||
|
||||
textPainter.paint(
|
||||
canvas,
|
||||
Offset(-textPainter.width / 2, -textPainter.height / 2),
|
||||
);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
List<Point?> _generatePreviewPoints(Size size) {
|
||||
final points = <Point?>[];
|
||||
final width = size.width * 0.4;
|
||||
|
||||
@@ -9,11 +9,14 @@ class LastImageAsBackground extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
if (image != null) {
|
||||
canvas.drawImage(image!, Offset.zero, ui.Paint()
|
||||
..blendMode = BlendMode.srcIn
|
||||
..filterQuality = ui.FilterQuality.high
|
||||
// ..isAntiAlias = true,
|
||||
);
|
||||
paintImage(
|
||||
canvas: canvas,
|
||||
rect: Offset.zero & size,
|
||||
image: image!,
|
||||
fit: BoxFit.cover,
|
||||
filterQuality: FilterQuality.high,
|
||||
isAntiAlias: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,23 +7,23 @@ class AboutMeScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 100),
|
||||
body:Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ContactUs(
|
||||
logo: const AssetImage("assets/NaserElziadna.jpg"),
|
||||
email: 'elzianda10@gmail.com',
|
||||
companyName: 'Naser Elzianda',
|
||||
phoneNumber: '+972584029927',
|
||||
dividerThickness: 2,
|
||||
website: 'https://www.nmmsoft.com',
|
||||
githubUserName: 'NaserElziadna',
|
||||
linkedinURL: 'https://www.linkedin.com/in/naser-hassan-b452411a1/',
|
||||
tagLine: 'Full Stack Developer',
|
||||
cardColor: Colors.white,
|
||||
companyColor: Colors.red,
|
||||
taglineColor: Colors.green,
|
||||
textColor: Colors.black,
|
||||
),
|
||||
logo: const AssetImage("assets/NaserElziadna.jpg"),
|
||||
email: 'elzianda10@gmail.com',
|
||||
companyName: 'Naser Elzianda',
|
||||
phoneNumber: '+972584029927',
|
||||
dividerThickness: 2,
|
||||
website: 'https://www.nmmsoft.com',
|
||||
githubUserName: 'NaserElziadna',
|
||||
linkedinURL: 'https://www.linkedin.com/in/naser-hassan-b452411a1/',
|
||||
tagLine: 'Full Stack Developer',
|
||||
cardColor: Colors.white,
|
||||
companyColor: Colors.red,
|
||||
taglineColor: Colors.green,
|
||||
textColor: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -300,10 +300,7 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
? null
|
||||
: drawController.stamp?.last?.image,
|
||||
),
|
||||
size: Size(
|
||||
kCanvasSize.width / 2,
|
||||
kCanvasSize.height / 2,
|
||||
),
|
||||
size: kCanvasSize,
|
||||
willChange: true,
|
||||
isComplex: true,
|
||||
child: const SizedBox.expand(),
|
||||
|
||||
Reference in New Issue
Block a user