-
Notifications
You must be signed in to change notification settings - Fork 52
Description
As we discussed on X, this would make it way easier in combination with a InteractiveViewer to allow the user to pan/zoom
This is Claude proposal:
Scribble Transform Plan
Problem
When rotating the phone, the scribble canvas size changes but existing scribble coordinates remain absolute. This causes drawings to appear in the top-left corner instead of maintaining their relative position.
Proposed Solution
Package author will add sketch.transform(Matrix4) method. Combined with Flutter's InteractiveViewer, this provides a complete solution.
Implementation
1. Track Original Canvas Size
Store the canvas dimensions when a scribble is first created:
Size? _originalCanvasSize;
// In a LayoutBuilder or post-frame callback when scribble starts
if (_originalCanvasSize == null && scribbleNotifier.currentSketch.lines.isNotEmpty) {
_originalCanvasSize = Size(canvasWidth, canvasHeight);
}2. Calculate Transform Matrix on Orientation Change
When canvas size changes, compute a Matrix4 to scale and center the sketch:
Matrix4 calculateTransform(Size originalSize, Size newSize) {
// Uniform scale to fit without stretching
final scaleX = newSize.width / originalSize.width;
final scaleY = newSize.height / originalSize.height;
final scale = min(scaleX, scaleY);
// Calculate centering offset
final scaledWidth = originalSize.width * scale;
final scaledHeight = originalSize.height * scale;
final offsetX = (newSize.width - scaledWidth) / 2;
final offsetY = (newSize.height - scaledHeight) / 2;
return Matrix4.identity()
..translate(offsetX, offsetY)
..scale(scale, scale);
}3. Apply Transform to Sketch
final transformedSketch = sketch.transform(matrix);4. Wrap in InteractiveViewer
Allow user to manually pan/zoom for fine adjustments:
InteractiveViewer(
boundaryMargin: EdgeInsets.all(20),
minScale: 0.5,
maxScale: 3.0,
child: Scribble(
notifier: scribbleNotifier,
drawPen: true,
drawEraser: true,
),
)5. Coordinate InteractiveViewer with ScribbleNotifier
Use the existing scaleFactor property to keep pen width consistent when zoomed:
InteractiveViewer(
onInteractionUpdate: (details) {
scribbleNotifier.setScaleFactor(details.scale);
},
// ...
)Benefits
- Pan/zoom handled by InteractiveViewer gestures
- Orientation changes auto-transform sketch to fit
- User can manually adjust if auto-transform isn't perfect
- Consistent pen width at any zoom level via scaleFactor
- Clean separation: package handles transform, Flutter handles interaction
Dependencies
- Waiting for
sketch.transform(Matrix4)to be added to scribble package - Could implement our own transform function as workaround if needed
Workaround (if needed before package update)
Create a helper function to transform sketch manually:
Sketch transformSketch(Sketch sketch, Matrix4 matrix) {
return Sketch(
lines: sketch.lines.map((line) {
return SketchLine(
points: line.points.map((point) {
final vector = matrix.transform3(Vector3(point.x, point.y, 0));
return Point(x: vector.x, y: vector.y, pressure: point.pressure);
}).toList(),
color: line.color,
width: line.width * matrix.getMaxScaleOnAxis(),
);
}).toList(),
);
}