mirror of
https://github.com/NaserElziadna/doddle.git
synced 2026-03-13 07:41:06 +08:00
majdolean ya habibit albi
This commit is contained in:
@@ -8,13 +8,21 @@ import 'package:doddle/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TextEffect extends PenEffect {
|
||||
BrushSettingsState get settings => globalRef.read(brushSettingsProvider(PenTool.textPen));
|
||||
|
||||
BrushSettingsState get settings =>
|
||||
globalRef.read(brushSettingsProvider(PenTool.textPen));
|
||||
|
||||
String get text => settings.getValue('text') ?? 'Hello';
|
||||
double get fontSize => settings.getValue('fontSize') ?? 20.0;
|
||||
bool get randomRotation => settings.getValue('randomRotation') ?? false;
|
||||
double get wordSpacing => settings.getValue('wordSpacing') ?? 0.0;
|
||||
double get letterSpacing => settings.getValue('letterSpacing') ?? 0.0;
|
||||
TextDirection? get textDirection {
|
||||
final text = settings.getValue('text') ?? '';
|
||||
// Check if text contains RTL characters
|
||||
final rtlPattern =
|
||||
RegExp(r'[\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]');
|
||||
return rtlPattern.hasMatch(text) ? TextDirection.rtl : TextDirection.ltr;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Path path, Paint paint) {
|
||||
@@ -30,32 +38,20 @@ class TextEffect extends PenEffect {
|
||||
letterSpacing: letterSpacing,
|
||||
),
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
textDirection: textDirection ?? TextDirection.rtl,
|
||||
);
|
||||
textPainter.layout();
|
||||
|
||||
for (var point in drawController.points!) {
|
||||
if (point?.offset == null) continue;
|
||||
|
||||
|
||||
final positions = getSymmetricalPositions(point!.offset!);
|
||||
|
||||
|
||||
for (var position in positions) {
|
||||
canvas.save();
|
||||
canvas.translate(position.dx, position.dy);
|
||||
|
||||
if (randomRotation) {
|
||||
|
||||
final rotation = (point.pressure ?? 0) * 2 * pi;
|
||||
canvas.rotate(rotation);
|
||||
}
|
||||
|
||||
textPainter.paint(
|
||||
canvas,
|
||||
Offset(-textPainter.width / 2, -textPainter.height / 2),
|
||||
);
|
||||
|
||||
canvas.restore();
|
||||
textPainter.layout();
|
||||
|
||||
textPainter.paint(canvas, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ class _PopoverState extends State<Popover> with SingleTickerProviderStateMixin {
|
||||
clipBehavior: Clip.antiAlias,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: 90.w,
|
||||
maxHeight: 93.h
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.cardColor,
|
||||
|
||||
@@ -21,9 +21,9 @@ class BrushPreviewPainter extends CustomPainter {
|
||||
final currentPenTool = ref.read(canvasNotifierProvider).penTool;
|
||||
|
||||
// Special handling for text brush preview
|
||||
if (currentPenTool == PenTool.textPen) {
|
||||
_drawTextPreview(canvas, size);
|
||||
} else {
|
||||
// if (currentPenTool == PenTool.textPen) {
|
||||
// _drawTextPreview(canvas, size);
|
||||
// } else {
|
||||
// Original wave preview for other brushes
|
||||
final points = _generatePreviewPoints(size);
|
||||
final controller = DrawController(
|
||||
@@ -46,7 +46,7 @@ class BrushPreviewPainter extends CustomPainter {
|
||||
_drawPreviewPoints(canvas, path, paint, effect, points);
|
||||
effect.paint(canvas, path, paint);
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:screen_recorder/screen_recorder.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
import '../../../generated/assets.gen.dart';
|
||||
import '../../../domain/models/draw_controller.dart';
|
||||
import '../../../domain/models/point.dart';
|
||||
@@ -29,17 +30,17 @@ class CanvasScreen extends ConsumerStatefulWidget {
|
||||
|
||||
class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
static Size kCanvasSize = Size.zero;
|
||||
// late bool ignorePointer;
|
||||
// late int pointerCount;
|
||||
final TransformationController _transformationController =
|
||||
TransformationController();
|
||||
bool showResetScaleTranslateToCanvas = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// ignorePointer = false;
|
||||
// pointerCount = 1;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// ref.read(canvasNotifierProvider.notifier).initializeEffects();
|
||||
ref.read(canvasNotifierProvider.notifier).setGlobalKey(CanvasScreen.globalKey!);
|
||||
ref
|
||||
.read(canvasNotifierProvider.notifier)
|
||||
.setGlobalKey(CanvasScreen.globalKey!);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,7 +107,22 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
body: _buildCanvas(),
|
||||
body: Stack(
|
||||
children: [
|
||||
_buildCanvas(),
|
||||
Positioned(
|
||||
right: 16,
|
||||
bottom: 80,
|
||||
child: Visibility(
|
||||
visible: showResetScaleTranslateToCanvas,
|
||||
child: FloatingActionButton(
|
||||
onPressed: _resetCanvas,
|
||||
child: const Icon(Icons.center_focus_strong),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomSheet: const ToolsWidget(),
|
||||
),
|
||||
);
|
||||
@@ -118,6 +134,7 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
return Container(
|
||||
color: Colors.purple[800],
|
||||
child: InteractiveViewer(
|
||||
transformationController: _transformationController,
|
||||
panEnabled: false,
|
||||
scaleEnabled: true,
|
||||
minScale: 0.1,
|
||||
@@ -140,18 +157,27 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
void _resetCanvas() {
|
||||
_transformationController.value = Matrix4.identity()
|
||||
..scale(1.0)
|
||||
..translate(1.w, -1.h);
|
||||
setState(() {
|
||||
showResetScaleTranslateToCanvas = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _handleGestureStart(PointerEvent pointerEvent) {
|
||||
if (ref.read(canvasNotifierProvider).isPanActive) return;
|
||||
// if (ignorePointer == false && pointerCount == 1) {
|
||||
if (ref.read(canvasNotifierProvider).isRandomColor) {
|
||||
final random = Random();
|
||||
final color = Color.fromRGBO(
|
||||
random.nextInt(256),
|
||||
random.nextInt(256),
|
||||
random.nextInt(256),
|
||||
1,
|
||||
);
|
||||
ref.read(canvasNotifierProvider.notifier).changeColor(color, true);
|
||||
if (ref.read(canvasNotifierProvider).isRandomColor) {
|
||||
final random = Random();
|
||||
final color = Color.fromRGBO(
|
||||
random.nextInt(256),
|
||||
random.nextInt(256),
|
||||
random.nextInt(256),
|
||||
1,
|
||||
);
|
||||
ref.read(canvasNotifierProvider.notifier).changeColor(color, true);
|
||||
}
|
||||
// }
|
||||
}
|
||||
@@ -159,47 +185,49 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
void _handleGestureUpdate(PointerEvent pointerEvent) {
|
||||
if (ref.read(canvasNotifierProvider).isPanActive) return;
|
||||
// if (ignorePointer == false && pointerCount == 1) {
|
||||
setState(() {
|
||||
kCanvasSize = Size(
|
||||
MediaQuery.of(context).size.width,
|
||||
MediaQuery.of(context).size.height - (AppBar().preferredSize.height),
|
||||
);
|
||||
var pinSpaceX = -20;
|
||||
var pinSpaceY = -160;
|
||||
setState(() {
|
||||
kCanvasSize = Size(
|
||||
MediaQuery.of(context).size.width,
|
||||
MediaQuery.of(context).size.height - (AppBar().preferredSize.height),
|
||||
);
|
||||
var pinSpaceX = -20;
|
||||
var pinSpaceY = -160;
|
||||
|
||||
Offset point = pointerEvent.localPosition;
|
||||
point = point.translate(
|
||||
-((kCanvasSize.width / 2) + pinSpaceX),
|
||||
-((kCanvasSize.height / 2) + pinSpaceY),
|
||||
);
|
||||
Offset point = pointerEvent.localPosition;
|
||||
point = point.translate(
|
||||
-((kCanvasSize.width / 2) + pinSpaceX),
|
||||
-((kCanvasSize.height / 2) + pinSpaceY),
|
||||
);
|
||||
|
||||
ref.read(canvasNotifierProvider.notifier).addPoint(Point(offset: point, pressure: pointerEvent.pressure));
|
||||
});
|
||||
ref
|
||||
.read(canvasNotifierProvider.notifier)
|
||||
.addPoint(Point(offset: point, pressure: pointerEvent.pressure));
|
||||
});
|
||||
// }
|
||||
}
|
||||
|
||||
void _handleGestureEnd(PointerEvent pointerEvent) {
|
||||
// if (ref.read(canvasNotifierProvider).isPanActive) return;
|
||||
// if (ignorePointer == false && pointerCount == 1) {
|
||||
setState(() {
|
||||
kCanvasSize = Size(
|
||||
MediaQuery.of(context).size.width,
|
||||
MediaQuery.of(context).size.height - (AppBar().preferredSize.height),
|
||||
);
|
||||
var pinSpaceX = -20;
|
||||
var pinSpaceY = -160;
|
||||
setState(() {
|
||||
kCanvasSize = Size(
|
||||
MediaQuery.of(context).size.width,
|
||||
MediaQuery.of(context).size.height - (AppBar().preferredSize.height),
|
||||
);
|
||||
var pinSpaceX = -20;
|
||||
var pinSpaceY = -160;
|
||||
|
||||
Offset point = pointerEvent.localPosition;
|
||||
point = point.translate(
|
||||
-((kCanvasSize.width / 2) + pinSpaceX),
|
||||
-((kCanvasSize.height / 2) + pinSpaceY),
|
||||
);
|
||||
Offset point = pointerEvent.localPosition;
|
||||
point = point.translate(
|
||||
-((kCanvasSize.width / 2) + pinSpaceX),
|
||||
-((kCanvasSize.height / 2) + pinSpaceY),
|
||||
);
|
||||
|
||||
ref.read(canvasNotifierProvider.notifier).addPoint(
|
||||
Point(offset: point),
|
||||
end: true,
|
||||
);
|
||||
});
|
||||
ref.read(canvasNotifierProvider.notifier).addPoint(
|
||||
Point(offset: point),
|
||||
end: true,
|
||||
);
|
||||
});
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -238,7 +266,7 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
|
||||
void _handleInteractionUpdate(ScaleUpdateDetails details) {
|
||||
print('pan update ${details.pointerCount}');
|
||||
if(details.pointerCount > 1) {
|
||||
if (details.pointerCount > 1) {
|
||||
//clear last point
|
||||
ref.read(canvasNotifierProvider.notifier).clearPoints();
|
||||
}
|
||||
@@ -249,12 +277,17 @@ class _CanvasScreenState extends ConsumerState<CanvasScreen> {
|
||||
}
|
||||
|
||||
void _handleInteractionStart(ScaleStartDetails details) {
|
||||
if(details.pointerCount > 1) {
|
||||
if (details.pointerCount > 1) {
|
||||
print('pan active ${details.pointerCount}');
|
||||
ref.read(canvasNotifierProvider.notifier).setPanActive(true);
|
||||
//clear last point
|
||||
ref.read(canvasNotifierProvider.notifier).clearPoints();
|
||||
setState(() {
|
||||
showResetScaleTranslateToCanvas = true;
|
||||
});
|
||||
}
|
||||
// _previousScale = _transformationController.value.getMaxScaleOnAxis();
|
||||
// _previousOffset = _transformationController.toScene(Offset.zero);
|
||||
// setState(() {
|
||||
// ignorePointer = details.pointerCount > 1;
|
||||
// pointerCount = details.pointerCount;
|
||||
|
||||
Reference in New Issue
Block a user