Files
BadNote/lib/editor/render/live_ink_painter.dart

57 lines
1.7 KiB
Dart
Raw Normal View History

// lib/editor/render/live_ink_painter.dart
//
// CustomPainter for the in-progress stroke (live) layer.
//
// Paints only the single EditorStroke? currently being drawn, with
// isComplete:false so perfect_freehand tapers the trailing end correctly.
// Kept in a separate RepaintBoundary so committed strokes are never
// re-rasterized on pointer-move events.
import 'package:flutter/material.dart';
import '../engine/stroke_geometry.dart';
import '../engine/stroke_model.dart';
/// Paints the single in-progress [EditorStroke] (or nothing when [live] is
/// null / empty). Use alongside [StaticInkPainter] in stacked [CustomPaint]s.
class LiveInkPainter extends CustomPainter {
const LiveInkPainter({
required this.live,
required this.pageSize,
2026-06-23 02:59:30 +08:00
this.thinning = kDefaultPenThinning,
});
/// The stroke currently being drawn, or null when idle.
final EditorStroke? live;
final Size pageSize;
2026-06-23 02:59:30 +08:00
/// perfect_freehand pressure→width response (from `PenConfig.pressureSensitivity`),
/// kept consistent with the static layer so the stroke doesn't change width
/// the instant it commits.
final double thinning;
@override
void paint(Canvas canvas, Size size) {
final stroke = live;
if (stroke == null || stroke.points.isEmpty) return;
2026-06-23 02:59:30 +08:00
final path = buildStrokeOutline(stroke, pageSize,
isComplete: false, thinning: thinning);
if (path.getBounds().isEmpty) return;
canvas.drawPath(
path,
Paint()
..color = Color(stroke.color)
..style = PaintingStyle.fill
..isAntiAlias = true,
);
}
@override
bool shouldRepaint(LiveInkPainter old) =>
2026-06-23 02:59:30 +08:00
!identical(old.live, live) ||
old.pageSize != pageSize ||
old.thinning != thinning;
}