Flutter Drawing App Code
Pubspec
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_colorpicker: any
flutter:
uses-material-design: true
..........................................................................................
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
class Draw extends StatefulWidget {
@override
_DrawState createState() => _DrawState();
}
class _DrawState extends State<Draw> {
Color selectedColor = Colors.black;
Color pickerColor = Colors.black;
double strokeWidth = 3.0;
List<DrawingPoints> points = List();
bool showBottomList = false;
double opacity = 1.0;
StrokeCap strokeCap = (Platform.isAndroid) ? StrokeCap.butt : StrokeCap.round;
SelectedMode selectedMode = SelectedMode.StrokeWidth;
List<Color> colors = [
Colors.red,
Colors.green,
Colors.blue,
Colors.amber,
Colors.black
];
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
color: Colors.greenAccent),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.album),
onPressed: () {
setState(() {
if (selectedMode == SelectedMode.StrokeWidth)
showBottomList = !showBottomList;
selectedMode = SelectedMode.StrokeWidth;
});
}),
IconButton(
icon: Icon(Icons.opacity),
onPressed: () {
setState(() {
if (selectedMode == SelectedMode.Opacity)
showBottomList = !showBottomList;
selectedMode = SelectedMode.Opacity;
});
}),
IconButton(
icon: Icon(Icons.color_lens),
onPressed: () {
setState(() {
if (selectedMode == SelectedMode.Color)
showBottomList = !showBottomList;
selectedMode = SelectedMode.Color;
});
}),
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
setState(() {
showBottomList = false;
points.clear();
});
}),
],
),
Visibility(
child: (selectedMode == SelectedMode.Color)
? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: getColorList(),
)
: Slider(
value: (selectedMode == SelectedMode.StrokeWidth)
? strokeWidth
: opacity,
max: (selectedMode == SelectedMode.StrokeWidth)
? 50.0
: 1.0,
min: 0.0,
onChanged: (val) {
setState(() {
if (selectedMode == SelectedMode.StrokeWidth)
strokeWidth = val;
else
opacity = val;
});
}),
visible: showBottomList,
),
],
),
)),
),
body: GestureDetector(
onPanUpdate: (details) {
setState(() {
RenderBox renderBox = context.findRenderObject();
points.add(DrawingPoints(
points: renderBox.globalToLocal(details.globalPosition),
paint: Paint()
..strokeCap = strokeCap
..isAntiAlias = true
..color = selectedColor.withOpacity(opacity)
..strokeWidth = strokeWidth));
});
},
onPanStart: (details) {
setState(() {
RenderBox renderBox = context.findRenderObject();
points.add(DrawingPoints(
points: renderBox.globalToLocal(details.globalPosition),
paint: Paint()
..strokeCap = strokeCap
..isAntiAlias = true
..color = selectedColor.withOpacity(opacity)
..strokeWidth = strokeWidth));
});
},
onPanEnd: (details) {
setState(() {
points.add(null);
});
},
child: CustomPaint(
child: Center(
child: Text(
"A",
style: TextStyle(
fontSize: 300,
color: Colors.white,
fontWeight: FontWeight.w700,
// fontStyle: FontStyle.italic,
letterSpacing: 8,
wordSpacing: 20,
// backgroundColor: Colors.yellow,
shadows: [
Shadow(
color: Colors.blueAccent,
offset: Offset(2, 1),
blurRadius: 10)
]),
),
),
size: Size.infinite,
foregroundPainter: DrawingPainter(
pointsList: points,
),
),
),
);
}
getColorList() {
List<Widget> listWidget = List();
for (Color color in colors) {
listWidget.add(colorCircle(color));
}
Widget colorPicker = GestureDetector(
onTap: () async {
showDialog(
context: this.context,
builder: (_) => AlertDialog(
title: const Text('Pick a color!'),
content: SingleChildScrollView(
child: ColorPicker(
pickerColor: pickerColor,
onColorChanged: (color) {
pickerColor = color;
},
enableLabel: true,
pickerAreaHeightPercent: 0.8,
),
),
actions: <Widget>[
FlatButton(
child: const Text('Save'),
onPressed: () {
setState(() => selectedColor = pickerColor);
Navigator.of(context).pop();
},
),
],
),
);
},
child: ClipOval(
child: Container(
padding: const EdgeInsets.only(bottom: 16.0),
height: 36,
width: 36,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.red, Colors.green, Colors.blue],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
)),
),
),
);
listWidget.add(colorPicker);
return listWidget;
}
Widget colorCircle(Color color) {
return GestureDetector(
onTap: () {
setState(() {
selectedColor = color;
});
},
child: ClipOval(
child: Container(
padding: const EdgeInsets.only(bottom: 16.0),
height: 36,
width: 36,
color: color,
),
),
);
}
}
class DrawingPainter extends CustomPainter {
DrawingPainter({this.pointsList});
List<DrawingPoints> pointsList;
List<Offset> offsetPoints = List();
@override
void paint(Canvas canvas, Size size) {
for (int i = 0; i < pointsList.length - 1; i++) {
if (pointsList[i] != null && pointsList[i + 1] != null) {
canvas.drawLine(pointsList[i].points, pointsList[i + 1].points,
pointsList[i].paint);
} else if (pointsList[i] != null && pointsList[i + 1] == null) {
offsetPoints.clear();
offsetPoints.add(pointsList[i].points);
offsetPoints.add(Offset(
pointsList[i].points.dx + 0.1, pointsList[i].points.dy + 0.1));
canvas.drawPoints(PointMode.points, offsetPoints, pointsList[i].paint);
}
}
}
@override
bool shouldRepaint(DrawingPainter oldDelegate) => true;
}
class DrawingPoints {
Paint paint;
Offset points;
DrawingPoints({this.points, this.paint});
}
enum SelectedMode { StrokeWidth, Opacity, Color }
Comments
Post a Comment