diff --git a/lib/domain/models/effects/custom_pen_effect.dart b/lib/domain/models/effects/custom_pen_effect.dart new file mode 100644 index 0000000..036e60b --- /dev/null +++ b/lib/domain/models/effects/custom_pen_effect.dart @@ -0,0 +1,71 @@ +import 'dart:ui'; +import 'dart:math' as math; + +import 'package:doddle/domain/models/effects/pen_effect.dart'; + +class CustomPenEffect extends PenEffect { + final _random = math.Random(); + + // Map to store effect data for each point + Map> _pointEffects = {}; + + @override + void paint(Canvas canvas, Path path, Paint paint) { + // Extract points from path by computing path metrics + final metrics = path.computeMetrics(); + for (var metric in metrics) { + final length = metric.length; + final numPoints = (length / 5).ceil(); // Sample points every 5 pixels + + for (var i = 0; i < numPoints; i++) { + final distance = (i * length) / (numPoints - 1); + final pos = metric.getTangentForOffset(distance)?.position; + + if (pos != null) { + _pointEffects[i] = List.generate(3, (_) => _PointEffect( + jitter: Offset( + _random.nextDouble() * 10 - 5, + _random.nextDouble() * 10 - 5 + ), + opacity: 0.3, + strokeWidth: drawController.penSize! * 0.5 + )); + + // Draw dots using stored effects + for (var effect in _pointEffects[i]!) { + canvas.drawCircle( + pos.translate(effect.jitter.dx, effect.jitter.dy), + effect.strokeWidth, + Paint() + ..color = drawController.currentColor.withOpacity(effect.opacity) + ..style = PaintingStyle.fill + ); + } + } + } + } + + // Draw original path with reduced opacity + canvas.drawPath( + path, + Paint() + ..color = drawController.currentColor.withOpacity(0.5) + ..strokeWidth = drawController.penSize! * 0.8 + ..strokeCap = StrokeCap.round + ..style = PaintingStyle.stroke + ); + } +} + +// Class to store effect data for each point +class _PointEffect { + final Offset jitter; + final double opacity; + final double strokeWidth; + + _PointEffect({ + required this.jitter, + required this.opacity, + required this.strokeWidth + }); +} \ No newline at end of file diff --git a/lib/domain/models/effects/glow_with_dots_effect.dart b/lib/domain/models/effects/glow_with_dots_effect.dart index 66bb226..0002c30 100644 --- a/lib/domain/models/effects/glow_with_dots_effect.dart +++ b/lib/domain/models/effects/glow_with_dots_effect.dart @@ -8,7 +8,8 @@ class GlowWithDotsEffect extends PenEffect { final pathWithDots = dashPath( path, - dashArray: CircularIntervalList([5, 10]), // Changed to create 5px dashes with 10px gaps + dashArray: CircularIntervalList([5 + , 10]), // Changed to create 5px dashes with 10px gaps ); canvas.drawPath( diff --git a/lib/presentation/common/widgets/tools/brush_tool_grid.dart b/lib/presentation/common/widgets/tools/brush_tool_grid.dart index f0b1730..1444906 100644 --- a/lib/presentation/common/widgets/tools/brush_tool_grid.dart +++ b/lib/presentation/common/widgets/tools/brush_tool_grid.dart @@ -16,6 +16,7 @@ class BrushToolGrid extends ConsumerWidget { BrushTool(penTool: PenTool.glowWithDotsPen, picture: Assets.svg.pen5Preview.svg()), BrushTool(penTool: PenTool.normalWithShaderPen, picture: Assets.svg.pen6Preview.svg()), BrushTool(penTool: PenTool.sprayPen, picture: Assets.svg.pen3Preview.svg()), + BrushTool(penTool: PenTool.customPen, picture: Assets.svg.pen4Preview.svg()), ]; final selectedPenTool = ref.watch(canvasProvider).penTool; diff --git a/lib/presentation/painting/sketcher.dart b/lib/presentation/painting/sketcher.dart index cab3b12..9eba85b 100644 --- a/lib/presentation/painting/sketcher.dart +++ b/lib/presentation/painting/sketcher.dart @@ -1,4 +1,5 @@ import 'package:doddle/domain/models/draw_controller.dart'; +import 'package:doddle/domain/models/effects/custom_pen_effect.dart'; import 'package:doddle/domain/models/effects/eraser_effect.dart'; import 'package:doddle/domain/models/effects/glow_effect.dart'; import 'package:doddle/domain/models/effects/glow_with_dots_effect.dart'; @@ -21,6 +22,7 @@ class Sketcher extends CustomPainter { Sketcher(this.controller, this.ref) : _effects = { + PenTool.customPen: CustomPenEffect()..initialize(ref), PenTool.eraserPen: EraserEffect()..initialize(ref), PenTool.sprayPen: SprayEffect()..initialize(ref), PenTool.glowPen: GlowEffect()..initialize(ref),