This commit is contained in:
Naser Elziadna
2024-11-30 16:03:58 +02:00
parent c4aa36bea3
commit 5cb06e854b
4 changed files with 76 additions and 1 deletions

View File

@@ -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<int, List<_PointEffect>> _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
});
}

View File

@@ -8,7 +8,8 @@ class GlowWithDotsEffect extends PenEffect {
final pathWithDots = dashPath(
path,
dashArray: CircularIntervalList<double>(<double>[5, 10]), // Changed to create 5px dashes with 10px gaps
dashArray: CircularIntervalList<double>(<double>[5
, 10]), // Changed to create 5px dashes with 10px gaps
);
canvas.drawPath(

View File

@@ -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;

View File

@@ -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),