notes/lib/canvas/my_painter.dart
lukas-heiligenbrunner 8e0cd05ded allow zooming on desktop when holding ctrl and scrolling
add prototype of selection mode, span up dashed rectangle
2022-12-02 00:25:37 +01:00

125 lines
3.7 KiB
Dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'paint_controller.dart';
import 'path/path_transform.dart';
import 'path/ring_number_provider.dart';
import 'screen_document_mapping.dart';
final Rect a4Page =
Rect.fromPoints(const Offset(.0, .0), const Offset(210, 210 * sqrt2));
class MyPainter extends CustomPainter {
double zoom;
Offset offset;
Size canvasSize;
PaintController controller;
late Pen activePen;
MyPainter(
{required this.zoom,
required this.offset,
required this.canvasSize,
required this.controller})
: super(repaint: controller) {
activePen = controller.activePen;
controller.addListener(() {
activePen = controller.activePen;
});
}
Offset _translatept(Offset pt, Size canvasSize) {
final scale = calcPageDependentScale(zoom, a4Page, canvasSize);
return translateDocumentToScreenPoint(pt, scale, offset);
}
Paint backgroundPaint = Paint()..color = Colors.white;
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.blue
..strokeCap = StrokeCap.square
..isAntiAlias = true;
// clipping canvas to reqired size
canvas.clipRect(Offset.zero & size);
canvas.drawColor(const Color(0xff6e6e6e), BlendMode.src);
canvas.drawRect(
Rect.fromPoints(_translatept(const Offset(0, .0), size),
_translatept(a4Page.bottomRight, size)),
backgroundPaint);
for (final stroke in controller.strokes) {
paint.color = stroke.color;
for (int i = 0; i < stroke.points.length - 1; i++) {
Offset pt1 = stroke.points[i].point;
pt1 = _translatept(pt1, size);
Offset pt2 = stroke.points[i + 1].point;
pt2 = _translatept(pt2, size);
final zoomedthickness = stroke.points[i].thickness * zoom;
// only temporary solution to differ from highlighter and pen
if (stroke.color.opacity != 1.0) {
final off = Offset(zoomedthickness / 2, zoomedthickness / 2);
canvas.drawPath(
Path()
..moveTo((pt1 - off).dx, (pt1 - off).dy)
..lineTo((pt1 + off).dx, (pt1 + off).dy)
..lineTo((pt2 + off).dx, (pt2 + off).dy)
..lineTo((pt2 - off).dx, (pt2 - off).dy)
..lineTo((pt1 - off).dx, (pt1 - off).dy),
paint
..style = PaintingStyle.fill
..strokeWidth = 0);
} else {
canvas.drawLine(pt1, pt2, paint..strokeWidth = zoomedthickness);
}
}
}
// active pen hover effects
switch (activePen) {
case Pen.eraser:
final pointerpos = controller.getPointerPosition();
if (pointerpos != null) {
final translatedPointerpos = _translatept(pointerpos, size);
canvas.drawCircle(
translatedPointerpos,
calcPageDependentScale(zoom, a4Page, canvasSize) * 2.0,
paint
..style = PaintingStyle.stroke
..color = Colors.grey);
}
break;
case Pen.selector:
final selection = controller.getSelection();
if (selection != null) {
final rectpath = (Path()
..addRect(Rect.fromPoints(_translatept(selection.topLeft, size),
_translatept(selection.bottomRight, size))))
.dashPath(RingNumberProvider([3, 5]));
canvas.drawPath(
rectpath,
paint
..style = PaintingStyle.stroke
..color = Colors.grey);
}
break;
default:
break;
}
}
@override
bool shouldRepaint(MyPainter oldDelegate) {
return oldDelegate.zoom != zoom || oldDelegate.offset != offset;
}
}