draw_your_image 0.6.0
draw_your_image: ^0.6.0 copied to clipboard
A Flutter package which enables users to draw with fingers in your designed UI.
draw_your_image #
A Flutter package for creating customizable drawing canvases with a declarative API.

Core Concept #
Fully declarative, fully customizable
- No controllers required - Manage stroke data in your widget state
- Customize everything - Control stroke behavior through simple callbacks
- Bring your own features - Implement undo/redo, zoom/pan, image export as your app needs
This package focuses on providing a flexible drawing widget, leaving app-specific features to you.
Features #
โจ Device-aware drawing - Distinguish between stylus, finger, and mouse input
๐จ Flexible stroke handling - Customize behavior per input device or any other criteria
๐๏ธ Built-in smoothing - Catmull-Rom spline interpolation included
โ๏ธ Fully customizable - Colors, widths, smoothing algorithms
๐งน Multiple erasing modes - Pixel-level and stroke-level erasing
๐ Intersection detection - Customizable stroke overlap detection
Quick Start #
class MyDrawingPage extends StatefulWidget {
@override
_MyDrawingPageState createState() => _MyDrawingPageState();
}
class _MyDrawingPageState extends State<MyDrawingPage> {
/// Store all the strokes on app side as state
List<Stroke> _strokes = [];
@override
Widget build(BuildContext context) {
return Draw(
strokes: _strokes, // pass strokes via
onStrokeDrawn: (stroke) {
// store new drawn stroke and rebuild
setState(() {
_strokes = [..._strokes, stroke];
});
},
);
}
}
That's it! The canvas accepts any input and draws with default settings.
Device-Aware Drawing with onStrokeStarted #
The onStrokeStarted callback lets you control stroke behavior based on input devices or any other criteria.
Stroke? Function(Stroke newStroke, Stroke? currentStroke)
Parameters:
newStroke- The stroke about to be startedcurrentStroke- The stroke currently being drawn (null if none)
Return:
- The stroke to draw (can be
newStroke,currentStroke, or a modified version) nullto reject the stroke
Example: Stylus draws, finger erases #
If you want to draw lines with stylus while erase them with a finger, the function can be implemented like below:
extension on PointerDeviceKind {
bool get isStylus =>
this ||
this == PointerDeviceKind.invertedStylus;
}
Stroke? customHandler(Stroke newStroke, Stroke? currentStroke) {
// if we have an ongoing stroke, just continue.
if (currentStroke != null) {
return currentStroke;
}
if (newStroke.deviceKind == PointerDeviceKind.stylus) {
// if stylus, draw black line
return newStroke.copyWith(color: Colors.black);
} else {
// if finger, erasor mode
return newStroke.copyWith(isErasing: true, width: 20.0);
}
}
Draw(
strokes: _strokes,
onStrokeDrawn: (stroke) => setState(() => _strokes.add(stroke)),
onStrokeStarted: customHandler,
)
Example: Stylus-only drawing #
If pre-defined utility functions fit to your needs, you can pick one of them.
Draw(
strokes: _strokes,
onStrokeDrawn: (stroke) => setState(() => _strokes.add(stroke)),
onStrokeStarted: stylusOnlyHandler, // Pre-defined utility
)
Pre-defined Utilities #
stylusOnlyHandler- Accept only stylus inputstylusPriorHandler- Prioritize stylus when drawing (palm rejection)
API Reference #
Draw Widget Properties #
| Property | Type | Required | Description |
|---|---|---|---|
strokes |
List<Stroke> |
โ | List of strokes to display |
onStrokeDrawn |
void Function(Stroke) |
โ | Called when a stroke is complete |
onStrokeStarted |
Stroke? Function(Stroke, Stroke?) |
Control stroke behavior based on input | |
onStrokeUpdated |
Stroke? Function(Stroke) |
Modify stroke in real-time as points are added | |
onStrokesRemoved |
void Function(List<Stroke>) |
Called when strokes are removed by erasing | |
strokeColor |
Color |
Default stroke color | |
strokeWidth |
double |
Default stroke width | |
backgroundColor |
Color |
Canvas background color | |
erasingBehavior |
ErasingBehavior |
Erasing mode (none, pixel, stroke) |
|
smoothingFunc |
Path Function(Stroke) |
Custom smoothing function | |
intersectionDetector |
IntersectionDetector |
Custom intersection detection function |
Stroke Properties #
class Stroke {
PointerDeviceKind deviceKind; // Input device type
List<Offset> points; // Stroke points
Color color; // Stroke color
double width; // Stroke width
ErasingBehavior erasingBehavior; // Erasing mode
}
ErasingBehavior #
enum ErasingBehavior {
none, // Normal drawing (default)
pixel, // Pixel-level erasing (BlendMode.clear)
stroke, // Stroke-level erasing (removes entire strokes)
}
Smoothing Modes #
Smoothing algorithm is also customizable. You can choose pre-defined functions below or make your own function.
SmoothingMode.catmullRom.converter // Smooth curves (default)
SmoothingMode.none.converter // No smoothing (straight lines)
Working with AI Assistants #
This package is designed to work well with AI coding assistants. If you want accurate response from AI agents, refer AI_GUIDE.md before asking.