Hey everyone. I'm Remixie and this is my entry for the Flutter Create contest. It's a technical drawing app that's optimized for touchscreen devices.
- Dart file size: 5,117 bytes
- License: Apache License 2.0
- Target platforms: Android and iOS
- Dart pub packages: scoped_model 1.0.1
- Device orientation support: Portrait
- Devices used during development:
- iPhone 6 (Simulator on macOS)
- Pixel 2 API 28 / Android Pie (Virtual Device in Android Studio)
- Pixel 3 with Android Pie
- Make a new Flutter Project (Flutter Application) in Android Studio
- Replace the generated
main.dartfile with the one provided in the zip file - Replace the generated
pubspec.yamlwith the one provided in the zip file - Make an
assetsdirectory in the same directory aslib - Move
Blueprint-Paper-by-RetinaShots.pngto theassetsdirectory - Click
packages getwhile in thepubspec.yamltab and verify that nothing is underlined with red inmain.dartupon saving it - Run
flutter run --release -d <device id>on the Flutter project directory but not before replacing<device id>
- To
make a point, tap somewhere on the blueprint paper area - To
make a line segment, tap somewhere else on the same area - To
remove your last point, click the undo button - To
reuse a point, tap on it - To
reset the area, click the trashcan button - To
move the straightedge, drag either or both of its black dots Tap on the straightedgeto make points and/or line segments at more precise coordinates
Note: If you tap on the straightedge at around the same coordinates where an existing point is located, your tap will be registered as a reuse, not as a new point aligned with the straightedge.
In terms of UI/UX, tons of details were taken into account. These are some of them:
- The undo button is intentionally placed more to the right for
faster editing Contrast is maximizedthrough the use of black and white on the paper area- The black dots can be tucked into a corner of the screen to
reduce visual clutter - Existing points appear every other tap so an end-user can
quickly see line segments - The AppBar background color is set to black so it can blend in with a touchscreen's upper bezel.
- The straightedge has a
hidden hitbox areathat detects when a user taps within 35 pixels of it - Line segments are drawn with StrokeCap.round so that
corners are smooth and notch-less - The blueprint background doubles as grid paper. This facilitates the
exact positioningof the straightedge, points and line segments
The main() function runs MyApp.
MyApp is a StatelessWidget that builds a MaterialApp whose home property is set to DrawPage.
DrawPage is a StatefulWidget that builds ScopedModel<MathModel> and returns a Scaffold.
The Scaffold returns a Stack widget whose children are a Container and another Stack. The Container has a Listener that detects when a user taps on it and calls MathModel.moveSEdge() and Painter. Its background is set to the public domain grid image asset provided by Retina Shots. The child Stack returns two instances of DragDot.
This is a Stateful widget that creates a DragDotState.
- Fields:
int i- This is the index of the DragDot instance
BuildContext bc- This references the BuildContext from
DrawPage
- This references the BuildContext from
This builds a Container that has a GestureDetector child.
This GestureDetector calls MathModel.moveSEdge() so this dot moves properly as an end-user drags it around.
- Fields:
var m- This references the
MathModelinstance fromDrawPage
- This references the
This handles the model logic.
-
Fields:
List<Offset> p- This list contains all user-defined points
static get hds- This is a constant double value that defines:
- The radi of the black dots (scaled at 1x
hds) - The radi of user-defined points (scaled at 1/5x
hds) - The max tolerance in distance from the straight edge until point placement becomes freehanded (scaled at 1x
hds)
- The radi of the black dots (scaled at 1x
- This is a constant double value that defines:
List<Offset> sEdge- This list contains the current offsets for the black dots of the straightedge
List<double> screen- This list contains the screen width and height in that order
-
Methods:
void moveSEdge(int i, Offset o)iis the black dot indexois the new black dot offset- This method changes the current position of the specified black dot
Offset getSEdgePoint(Offset o)ois the user defined point- This method returns the closest point to
othat's on the straightege
void addPoint(Offset o)ois the user defined point- This method determines whether
ois a reuse of an existing point, a point that should snap to the straightedge or just a freehanded point. The determined offset is then sent top
This is a CustomPainter class that handles the rendering of blueprint paper objects.
- Fields:
List<Offset> u- This list contains all user-defined points
List<Offset> sEdge- This list contains the current offsets for the black dots of the straightedge
- Methods:
void paint()- This draws all the points in
u, line segments, the straightedge and its black dots
- This draws all the points in
Blueprint Touch has a long way to go before it becomes the standard for technical drawings on touchscreen devices. This is the current list of future developments, ordered by priority:
- A protractor tool for making exact angles
- The addition of non-obstrusive labels and measurements
- An eraser tool to delete a particular line segment or point
- Transform the blueprint paper area to be a zoomable viewport
ETA for these developments: Q3 2019
boeledi. (2018, March 21). Flutter: how to prevent device orientation changes and force portrait? Retrieved March 21, 2019, from https://stackoverflow.com/questions/44179889/flutter-sdk-set-background-image
Bourne, M. (n.d.). Perpendicular Distance from a Point to a Line. Retrieved March 21, 2019, from https://www.intmath.com/plane-analytic-geometry/perpendicular-distance-point-line.php
Choudhary, H. (2018, September 05). Installation of Flutter and setup on MAC. Retrieved March 22, 2019, from https://www.youtube.com/watch?v=Xy-qHlaHr6c
Kumar, A. (2017, May 25). Flutter SDK Set Background image. Retrieved March 20, 2019, from https://stackoverflow.com/questions/44179889/flutter-sdk-set-background-image
Rumann. (2019, January 22). Drawing Custom Shapes in Flutter using a Custom Painter. Retrieved from https://zocada.com/drawing-custom-shapes-in-flutter-using-custompainter/
SnakeyHips. (2018, December 15). SnakeyHips/drawapp. Retrieved March 10, 2019, from https://github.com/SnakeyHips/drawapp
Stacky. (2014, November 2). How to calculate corner positions/marks of a rotated/tilted rectangle? Retrieved March 11, 2019, from https://gamedev.stackexchange.com/questions/86755/how-to-calculate-corner-positions-marks-of-a-rotated-tilted-rectangle
StrokeCap property. (n.d.). Retrieved March 20, 2019, from https://docs.flutter.io/flutter/dart-ui/Paint/strokeCap.html
Write your first Flutter app, part 1. (n.d.). Retrieved March 1, 2019, from https://flutter.dev/docs/get-started/codelab
Write Your First Flutter App, part 2. (n.d.). Retrieved March 3, 2019, from https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/
Xia, M., Sullivan, M., & Williams, J. (n.d.). Build Native Mobile Apps with Flutter. Retrieved March 6, 2019, from https://www.udacity.com/course/build-native-mobile-apps-with-flutter--ud905
