A painting app, but the 'paint' is cubes.
For making paintings that don’t make sense, like Escher did.
It's a free app on iOS and Android. It's just a demo to get a Flutter job (Here's my cv)!
Add lines of cubes | Pan and zoom | Erase |
---|---|---|
Places slices of cubes... | ...that you pick from a menu |
---|---|
- A standalone Flutter app working on Android and iOS using Provider.
- StatelessWidgets wherever possible.
- There's a documentation comment at the top of every class.
- The main page is PainterPage. This contains all the widgets that are draw.
- The Brusher draws AnimatedCubes while you drag a line of cubes.
- The Animator turns them into StaticCubes when you've finished dragging a line of cubes.
- The Persister saves the Position of each cube in a list of CubeInfos in the Painting class.
- Animator and Persister are mixins for the Paintings Provider.
All buttons are hexagon shaped to match the angles of the isometric grid. There have Icons, AssetIcons (downloaded from fluttericon.com), Cubes and Thumbnails of Paintings.
ElevatedButton and TextButton ButtonStyle.shape is set to my HexagonBorder which extends OutlinedBorder in a similar way to CircleBorder.
There are StaticCubes and animated cubes (BrushCubes and GrowingCubes). Their appearance can be WholeUnitCube, SliceUnitCube or WireUnitCube.
The Gesturer passes onScale* and onTap* gesture to two types of GestureHandler, Brusher and PanZoomer The Brusher creates or erases lines of cubes or single Slices of cube. The PanZoomer modifies the PanZoom.scale and PanZoom.offset
The Persister stores and persists the position and type of cubes (CubeInfo) in a map of <fileName, Painting>. The PaintingBank uses mixin Persister, but also mixin Animator because it needs to animate the current painting when it is being created and loaded.
There are three coordinate spaces, screen, UnitOffset and Position.
These classes transform positions between them. Position is in a skewed grid space allowing an
isometric grid to be saved in x, y integer Positions. The UnitOffset comes out of the grid space
into normal cartesian coordinates, but without the PanZoom scale and offset factored in. The screen
space is the unit offset transformed by the PanZoom scale and offset.
- All the mathematical functions have tests.
- All the persisted classes have json tests.
- There are no widget tests per se.
- provider
- path_provider.
Local files are persisted with jsonEncode & jsonDecode.
StatelessWidget StatefulWidget Stack Transform Tooltip SizedBox ElevatedButton TextButton Row Column Container Icon Scaffold Drawer CustomPaint AlertDialog SafeArea LayoutBuilder MaterialApp WillPopScope Divider ListView Center Text RichText Provider Align Navigator AnimatedBuilder SingleTickerProviderStateMixin State BackdropFilter Padding
ThemeData BoxDecoration TooltipThemeData Clipboard ChangeNotifierProvider Offset ButtonStyle IconData OutlinedBorder MaterialStateProperty ShapeBorder Path List AnimationController Duration Paint Alignment LinearGradient UnmodifiableListView ChangeNotifier BuildContext