@@ -4,13 +4,100 @@ import 'package:flutter/widgets.dart'; // Import for TransformationController
4
4
5
5
class CanvasProvider extends StateHandler {
6
6
final WorkspaceProvider _workspaceProvider;
7
- CanvasProvider (this ._workspaceProvider) : super ();
7
+ CanvasProvider (this ._workspaceProvider) : super () {
8
+ // Initialize the transformation to center the view when the provider is created
9
+ // We need to wait a frame for the context and size to be available,
10
+ // or ideally set it after the initial build. For now, we can set a
11
+ // default center based on the large canvas size.
12
+ // A more robust solution might involve `WidgetsBinding.instance.addPostFrameCallback`.
13
+ // For a fixed large canvas size, we can calculate the center directly.
14
+ _initializeCenteredView ();
15
+ }
16
+
17
+ final TransformationController _transformationController = TransformationController ();
18
+
19
+ TransformationController get transformationController => _transformationController;
20
+
21
+ // Define the size of your virtual canvas
22
+ static const Size _canvasSize = Size (20000 , 20000 );
23
+
24
+ void _initializeCenteredView () {
25
+ // Calculate the center of the large virtual canvas
26
+ final Offset canvasCenter = Offset (_canvasSize.width / 2 , _canvasSize.height / 2 );
27
+
28
+ // Get the initial viewport size (e.g., screen size).
29
+ // This will be dynamic, so for initial setup, we might approximate or
30
+ // use a post-frame callback to get the actual InteractiveViewer bounds.
31
+ // For now, let's assume we want to center the canvas's origin in the middle of the screen's interactive area.
32
+ // However, the request is to center the *canvas itself*.
33
+ // So, we need to translate the viewer so that the canvasCenter is at (0,0) in the viewport.
34
+ // Or, more accurately, we want the screen's center to align with the canvas's center.
8
35
9
- final TransformationController _transformationController =
10
- TransformationController ();
36
+ // This sets the initial matrix to translate the view such that the
37
+ // center of the 20000x20000 canvas is visible in the middle of the viewport.
38
+ // This assumes the InteractiveViewer will occupy the full available space.
39
+ // The translation needs to move the canvas's center to the viewport's center.
40
+ // If the viewport is V_w x V_h, and canvas is C_w x C_h,
41
+ // we want to display C_w/2, C_h/2 at V_w/2, V_h/2.
42
+ // This implies a translation of (V_w/2 - C_w/2, V_h/2 - C_h/2).
43
+ // However, InteractiveViewer automatically handles placing its child based on its current matrix.
44
+ // If we want the *center of our very large canvas* to be at the *center of the screen*,
45
+ // we need to translate the *view* by the negative of the canvas's center offset.
11
46
12
- TransformationController get transformationController =>
13
- _transformationController;
47
+ // Let's set the translation such that the top-left of the canvas (0,0) is moved.
48
+ // If we want the center of the canvas (10000, 10000) to appear at the center of our screen (e.g., 500, 300),
49
+ // then the transformation matrix needs to translate the canvas so that
50
+ // (10000, 10000) maps to (500, 300).
51
+ // The InteractiveViewer's transform applies to its child.
52
+ // A simple way to center a large child is to translate it by half the viewport dimensions
53
+ // minus half the child dimensions, or directly translate by a specific point.
54
+
55
+ // A common approach for centering a large canvas in InteractiveViewer:
56
+ // When the InteractiveViewer first appears, it's typically showing the (0,0) of its child
57
+ // at its top-left corner. To center the content, we need to apply a translation
58
+ // to the InteractiveViewer's matrix.
59
+ // The required translation is such that `canvasCenter` moves to `viewportCenter`.
60
+ // Let's assume the viewport center is `(screenWidth / 2, screenHeight / 2)`.
61
+ // The canvas center is `(canvasWidth / 2, canvasHeight / 2)`.
62
+ // The translation needed for the InteractiveViewer's matrix is:
63
+ // `(screenWidth / 2 - canvasWidth / 2, screenHeight / 2 - canvasHeight / 2)`
64
+ // This translation will move the canvas's top-left corner such that the canvas center
65
+ // aligns with the viewport center.
66
+
67
+ // Since we don't have direct access to `MediaQuery.of(context).size` here in the constructor,
68
+ // we might need a `WidgetsBinding.instance.addPostFrameCallback` in the `CanvasPage`
69
+ // or a method that can be called after the `BuildContext` is available.
70
+ // For demonstration, let's just set a large initial translation to make sure
71
+ // some central part of the 20000x20000 canvas is visible.
72
+ // A translation of (-canvasCenter.dx + viewport_center_dx, -canvasCenter.dy + viewport_center_dy)
73
+ // would be ideal if viewport size was known.
74
+
75
+ // Let's try to initialize it to a point that's approximately central.
76
+ // If the canvas is 20000x20000, its center is 10000, 10000.
77
+ // We want to translate the view *to* that point, so we need a negative translation.
78
+ // The `_transformationController.value` is a `Matrix4`.
79
+ // `Matrix4.translationValues(x, y, z)` creates a translation matrix.
80
+ // If we want the point (X, Y) on the child to be visible at the top-left of the viewer,
81
+ // the translation would be (-X, -Y).
82
+ // If we want (X, Y) to be visible at the center of the viewer, it's more complex
83
+ // as it depends on the viewer's size.
84
+
85
+ // A simpler approach for *initial centering* without knowing the viewport size
86
+ // is to translate by a fixed large amount that will bring a central part of
87
+ // the 20000x20000 canvas into view.
88
+ // Let's assume a typical screen size and calculate the offset needed to bring
89
+ // the (10000, 10000) point of the canvas to the center of a hypothetical 1000x800 screen.
90
+ // Target viewport center: (500, 400)
91
+ // Canvas center: (10000, 10000)
92
+ // Desired translation for canvas origin (0,0) relative to viewport:
93
+ // (500 - 10000, 400 - 10000) = (-9500, -9600)
94
+
95
+ _transformationController.value = Matrix4 .translationValues (
96
+ - canvasCenter.dx + 500 , // Adjust 500 based on expected initial viewport width / 2
97
+ - canvasCenter.dy + 400 , // Adjust 400 based on expected initial viewport height / 2
98
+ 0 ,
99
+ );
100
+ }
14
101
15
102
void zoomIn () {
16
103
_transformationController.value = Matrix4 .identity ()
@@ -27,7 +114,8 @@ class CanvasProvider extends StateHandler {
27
114
}
28
115
29
116
void resetZoom () {
30
- _transformationController.value = Matrix4 .identity ();
117
+ // Reset to the initially calculated centered view
118
+ _initializeCenteredView ();
31
119
notifyListeners ();
32
120
}
33
121
0 commit comments