fldraw 0.1.0
fldraw: ^0.1.0 copied to clipboard
The open-source tldraw alternative for building infinite canvas apps in Flutter.
fldraw #
A powerful, extensible, and high-performance infinite canvas and diagramming library for Flutter, inspired by tldraw and eraser.io
fldraw
provides a complete toolkit for building applications that require node-based editors, whiteboarding, or any kind of interactive canvas. It's built from the ground up with performance and customization in mind, using a custom rendering pipeline to ensure a smooth experience even with a large number of objects.
✨ Features #
- Infinite Canvas: Pan and zoom on a limitless canvas.
- Rich Toolset: Pre-built tools for selection, shapes (rectangles, circles), arrows, lines, free-hand drawing, text, and figures.
- Node-Based System: Create complex nodes with custom headers, content, and editable fields.
- Smart Attachments: Arrows intelligently snap and attach to the borders of nodes and shapes.
- High Performance: Built on a custom
RenderObject
for efficient rendering and smooth interaction. - State Management with BLoC: A clear and predictable state management architecture.
- Powerful Controller API: Programmatically control the canvas, manage tools, and manipulate objects from your own widgets.
- Undo/Redo History: A robust, built-in history stack for all major actions.
- Keyboard Shortcuts: Speed up your workflow with intuitive keyboard shortcuts for tools and actions.
- Text-to-Diagram (fldraw-lang): A simple, text-based language to programmatically generate entire diagrams.
- Customizable UI: Use builders to completely customize the appearance of nodes, context menus, and more coming soon.
📖 Table of Contents #
- Installation
- Quick Start
- Core Concepts
- Advanced Usage
- Contributing
- Star History
- Author
- Support the project
- License
📦 Installation #
Add fldraw
to your pubspec.yaml
file:
dependencies:
fldraw: ^latest_version
Then, run flutter pub get
in your terminal.
🚀 Quick Start #
Getting started with fldraw
is simple. Wrap your canvas area with the FlDraw
widget and provide it with an FlDrawCanvas
and a FlToolbar
.
import 'package:fldraw/fldraw.dart';
import 'package:flutter/material.dart';
class MyDiagramPage extends StatefulWidget {
const MyDiagramPage({super.key});
@override
State<MyDiagramPage> createState() => _MyDiagramPageState();
}
class _MyDiagramPageState extends State<MyDiagramPage> {
FlDrawController? controller;
@override
Widget build(BuildContext context) {
return Scaffold(
body: FlDraw(
// The onControllerCreated callback gives you access to the controller
// for programmatic interaction with the canvas.
onControllerCreated: (c) {
setState(() {
controller = c;
});
},
child: Stack(
alignment: Alignment.center,
children: [
// The main canvas widget
const FlDrawCanvas(debug: true), // Set debug to true for helpful overlays
// The toolbar for selecting tools
Positioned(
top: 24,
child: FlToolbar(svgs: const []), // svgs list is for a future feature
),
// A panel to show the undo/redo history
if (controller != null)
Positioned(
bottom: 24,
left: 24,
child: SizedBox(
height: 200,
width: 250,
child: Card(
child: HistoryPanel(controller: controller!),
),
),
),
],
),
),
);
}
}
🧠 Core Concepts #
FlDraw
Widget #
This is the root widget of the library. It sets up all the necessary BLoCs (CanvasBloc
, ToolBloc
, SelectionBloc
) and provides them to the widget tree. It is the entry point for using the library.
onControllerCreated
: A crucial callback that provides you with anFlDrawController
instance once the canvas is initialized.
FlDrawCanvas
#
This is the main widget that renders the infinite canvas, grid, nodes, and all drawing objects. It handles all user interactions like panning, zooming, and drawing.
debug
: When set totrue
, it displays useful information like the current viewport coordinates, zoom level, and selection count.
FlDrawController
#
The controller is your primary tool for interacting with the canvas programmatically. It provides a clean, high-level API to abstract away the underlying BLoC architecture.
- Streams: Listen to
canvasStateStream
,selectionStateStream
, andtoolStateStream
to react to changes. - Methods: Call methods like
undo()
,redo()
,setTool()
,addNode()
,zoomIn()
,centerView()
, andloadProject()
.
Toolbar & Tools #
The FlToolbar
widget provides a ready-made UI for selecting the active tool. The canvas behavior changes based on the currently selected tool in the ToolBloc
. Keyboard shortcuts are also available to quickly switch between tools.
Tool | Shortcut | Description |
---|---|---|
Select | V |
Select, move, and resize objects. |
Rectangle | R |
Draw a rectangle shape. |
Circle | O |
Draw a circle/oval shape. |
Arrow | A |
Draw an arrow connecting two points. |
Line | L |
Draw a line. |
Pencil | D |
Draw a free-hand stroke. |
Text | T |
Create a text object. |
Figure | F |
Create a dashed group container. |
Modifier Keys for Enhanced Control #
You can hold down modifier keys to enhance the behavior of tools and actions, providing more precise control over your creations.
Key(s) | Action | Description |
---|---|---|
Shift |
Draw Perfect Shapes | While drawing with the Rectangle or Circle tool, hold Shift to lock the aspect ratio, creating a perfect square or circle. |
Shift |
Draw Locked-Angle Lines/Arrows | While drawing with the Line or Arrow tool, hold Shift to snap the line to 45-degree angle increments (0°, 45°, 90°, etc.). |
Shift + Click |
Multi-Select | While using the Select tool, hold Shift and click on objects to add them to your current selection without deselecting others. |
Ctrl /Cmd + Click |
Multi-Select (Alternative) | Same as Shift + Click, allows for adding objects to the current selection. |
Shift + Ctrl /Cmd |
Draw Orthogonal Arrows | While drawing with the Arrow tool, hold both Shift and Ctrl /Cmd to create an orthogonal (right-angled) connector line. |
🛠️ Advanced Usage #
Programmatic Control with FlDrawController
#
Once you have the controller from the onControllerCreated
callback, you can perform a wide variety of actions.
// Change the active tool to Rectangle
controller.setTool(EditorTool.square);
// Add a new node to the canvas
controller.addNode(
NodeInstance(
state: NodeState(),
offset: const Offset(100, 150),
heading: 'My First Node',
value: 'This was added from code!',
),
);
// Zoom out and center the view
controller.zoomOut();
controller.centerView();
Text-to-Diagram with FlDrawParser
#
fldraw
includes a powerful parser for a simple, text-based language to define entire diagrams. This is perfect for generating diagrams from code, versioning them in git, or building integrations.
void generateDiagramFromText() {
// 1. Define your diagram using fldraw-lang syntax
const myDiagramCode = """
// This is a comment
StartPoint [shape: circle, text: "Start"]
Decision [shape: node, heading: "Make a Choice"]
EndPoint [shape: rect, text: "End"]
// Define relationships
StartPoint -> Decision
Decision -> EndPoint
""";
// 2. Create a parser and generate the JSON
final parser = FlDrawParser();
final jsonString = parser.parse(myDiagramCode);
final projectData = jsonDecode(jsonString);
// 3. Load the generated project into the canvas
controller?.loadProject(projectData);
}
This will automatically parse the text, lay out the nodes, and render the complete diagram on the canvas.
Customizing Nodes #
You can completely change the appearance of nodes by providing builder functions to the FlDrawCanvas
widget.
headerBuilder
: Customizes the header of a node.nodeBuilder
: Replaces the entire node widget with your own implementation, giving you full control.
FlDrawCanvas(
headerBuilder: (context, node, onToggleCollapse) {
// Return your own custom header widget here
return Container(
padding: const EdgeInsets.all(12),
color: Colors.deepPurple,
child: Row(
children: [
Icon(Icons.api, color: Colors.white),
const SizedBox(width: 8),
Text(
node.heading ?? 'Custom Node',
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
],
),
);
},
)
Roadmap & Future Features #
fldraw
is under active development. My goal is to make it the most powerful and easy-to-use diagramming library for Flutter. Below is a list of planned features and improvements. Contributions are highly welcome!
☐ Style & Property Inspector: Implement a robust styling system (fill color, stroke, text properties) and a property panel widget to edit selected objects.
☐ Mobile & Touchscreen Enhancements: Add intuitive two-finger gestures like pinch-to-zoom and two-finger pan.
☐ Contextual Mobile UI: Create a "delete" button or menu that appears above selected objects for easier interaction on touch devices.
☐ Canvas Minimap: Add a small navigator view, similar to tldraw
, for a high-level overview and quick panning.
☐ Desktop-Style Menu Bar: Implement a classic menu bar (File
, Edit
, View
) with common actions like Export and a list of keyboard shortcuts.
☐ Enhanced Exporting: Add functionality to export the canvas as an image (PNG/SVG).
☐ Improved Example Project: Enhance the example application to demonstrate saving and loading project state to/from a file.
Contributing ❤️ #
Contributions are welcome and greatly appreciated! fldraw
is an open-source project, and we'd love to see it grow with the help of the community.
If you'd like to contribute, please feel free to:
- Report a bug: Create an issue detailing the problem you've encountered.
- Suggest a feature: Open an issue to discuss a new feature or enhancement.
- Submit a pull request:
- Fork the repository.
- Create a new branch for your feature (
git checkout -b feature/amazing-feature
). - Make your changes.
- Commit your changes (
git commit -m 'Add some amazing feature'
). - Push to the branch (
git push origin feature/amazing-feature
). - Open a Pull Request.
Star History #
Author ✍️ #
This project is authored and maintained by Yash Makan.
Building software in public and sharing everything I learn along the way.
I am currently open looking for new job opportunities and interesting contract projects. If you are looking for a dedicated Flutter developer or have an exciting project in mind, please feel free to reach out 🙏
- Email: contact@yashmakan.com
- Website: yashmakan.com
- LinkedIn: linkedin.com/in/yashmakan
- GitHub: @yashmakan
- Cal.com: @yashmakan
Support The Project #
If fldraw
has been useful to you, please consider giving it a ⭐️ on GitHub!
For those who wish to provide more direct support, you can:
Your support helps in the ongoing development and maintenance of the project. Thank you!
License 📜 #
fldraw
is released under the MIT License. See the LICENSE
file for more details.