{"id":22962335,"url":"https://github.com/zonble/flutter_turtle","last_synced_at":"2026-04-02T02:53:52.270Z","repository":{"id":56830395,"uuid":"231223588","full_name":"zonble/flutter_turtle","owner":"zonble","description":"Turtle graphics for Flutter. It simply uses a custom painter to draw graphics by a series of Logo-like commands.","archived":false,"fork":false,"pushed_at":"2025-07-22T15:49:40.000Z","size":47909,"stargazers_count":49,"open_issues_count":0,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-13T06:42:43.654Z","etag":null,"topics":["dart","flutter","graphics","turtle","turtle-graphics"],"latest_commit_sha":null,"homepage":"https://zonble.github.io/flutter_turtle/","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zonble.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-01-01T14:04:34.000Z","updated_at":"2025-07-22T15:47:29.000Z","dependencies_parsed_at":"2025-08-13T06:34:02.225Z","dependency_job_id":"b83c0d0a-2552-40a4-be04-af3a577b743a","html_url":"https://github.com/zonble/flutter_turtle","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/zonble/flutter_turtle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonble%2Fflutter_turtle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonble%2Fflutter_turtle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonble%2Fflutter_turtle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonble%2Fflutter_turtle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zonble","download_url":"https://codeload.github.com/zonble/flutter_turtle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zonble%2Fflutter_turtle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273092937,"owners_count":25044435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","graphics","turtle","turtle-graphics"],"created_at":"2024-12-14T19:16:34.338Z","updated_at":"2026-04-02T02:53:52.247Z","avatar_url":"https://github.com/zonble.png","language":"Dart","readme":"# flutter_turtle\n\n[![pub package](https://img.shields.io/pub/v/flutter_turtle.svg)](https://pub.dev/packages/flutter_turtle)\n\n`flutter_turtle` is a simple yet powerful implementation of turtle graphics for Flutter. It leverages Flutter's `CustomPainter` to draw graphics using a declarative, Logo-like Domain-Specific Language (DSL) written entirely in Dart.\n\n\n\u003c!-- TOC --\u003e\n\n- [flutterturtle](#flutterturtle)\n    - [What is Turtle Graphics?](#what-is-turtle-graphics)\n    - [Why I made this?](#why-i-made-this)\n    - [Example](#example)\n    - [Usage](#usage)\n    - [Technical Details \u0026 Architecture](#technical-details--architecture)\n        - [1. The Command DSL](#1-the-command-dsl)\n        - [2. Compilation](#2-compilation)\n        - [3. Rendering Pipeline](#3-rendering-pipeline)\n        - [4. Animation Mechanism](#4-animation-mechanism)\n    - [Flutter Turtle DSL](#flutter-turtle-dsl)\n        - [Flow control](#flow-control)\n        - [Macros](#macros)\n    - [Supported Commands](#supported-commands)\n        - [Turtle motion \u0026 Styling](#turtle-motion--styling)\n        - [Flow control](#flow-control)\n        - [Macros](#macros)\n\n\u003c!-- /TOC --\u003e\n\n## What is Turtle Graphics?\n\nTurtle graphics is a popular method for introducing programming to beginners. It involves a \"turtle\" (an on-screen cursor) that carries a pen. By giving commands like \"move forward,\" \"turn right,\" and \"pen down,\" you can create complex geometric shapes and intricate patterns. It was a key feature of the Logo programming language and remains a foundational concept in computer science education.\n\nFor further information about turtle graphics, please refer to Wikipedia:\n- [Turtle graphics - Wikipedia](https://en.wikipedia.org/wiki/Turtle_graphics)\n\n## Why I made this?\n\nBuilding a [Domain-Specific Language (DSL)](https://en.wikipedia.org/wiki/Domain-specific_language) within Dart is an excellent exercise in API design, and turtle graphics are a universally engaging way to introduce programming concepts through visual feedback!\n\n## Example\n\n![screenshot.png](https://raw.githubusercontent.com/zonble/flutter_turtle/master/screenshot.png)\n\nA quick example:\n\n```dart\n@override\nWidget build(BuildContext context) {\n  return Scaffold(\n    appBar: AppBar(title: Text(widget.title)),\n    body: TurtleView(\n      child: Container(),\n      commands: [\n        PenDown(),\n        SetColor((_) =\u003e Color(0xffff9933)),\n        SetStrokeWidth((_) =\u003e 2),\n        Repeat((_) =\u003e 20, [\n          Repeat((_) =\u003e 180, [\n            Forward((_) =\u003e 25.0),\n            Right((_) =\u003e 20),\n          ]),\n          Right((_) =\u003e 18),\n        ]),\n        PenUp(),\n      ],\n    ),\n  );\n}\n```\n\nA Flutter web app example is available at [https://zonble.github.io/flutter_turtle/](https://zonble.github.io/flutter_turtle/)\n\n## Usage\n\n`flutter_turtle` provides two core visualization widgets:\n\n- `TurtleView`: Serves as your canvas and immediately renders the fully evaluated graphics based on the provided commands.\n- `AnimatedTurtleView`: An animated variant that sequentially visualizes the turtle's drawing process over time.\n\nTo use them, simply instantiate `TurtleView` or `AnimatedTurtleView`, pass your declarative commands via the `commands` parameter, and embed the widget directly into your Flutter widget tree.\n\n## Technical Details \u0026 Architecture\n\n`flutter_turtle` is built to be efficient, extensible, and seamlessly integrated into Flutter's rendering pipeline. The architecture is primarily divided into three stages: the **DSL Command Definition**, the **Compiler**, and the **Painter**.\n\n### 1. The Command DSL\n\nThe library provides a set of classes (e.g., `Forward`, `Right`, `Repeat`, `IfElse`) that represent Logo-like instructions. Unlike a traditional interpreter that reads a text script, the DSL is constructed using native Dart objects. This provides full type safety, code completion, and allows you to seamlessly mix Flutter logic (like using Flutter `Color` or `BuildContext` state) directly into your turtle commands.\n\n### 2. Compilation\n\nBefore any graphics are drawn, the tree of nested `TurtleCommand` objects is processed by the `TurtleCompiler`. The compiler evaluates flow-control commands (`Repeat`, `If`, `IfElse`) and flattens the execution tree into a linear sequence of atomic `Instruction` objects.\n\n- **Macros:** Macros are managed during compilation. A `SetMacro` command registers a sub-tree of commands, which are injected and compiled in place whenever a `RunMacro` command is encountered.\n- **State Management:** While compiling, the framework does not draw anything. It simply prepares a highly optimized sequence of operations.\n\n### 3. Rendering Pipeline\n\nThe actual drawing happens inside `TurtlePainter`, which is a `CustomPainter` implementation.\n\n- `TurtlePainter` receives the compiled list of `Instruction` objects.\n- It initializes a `PaintContext` (providing access to the `Canvas` and `Paint` objects) and a `TurtleState` (which tracks the turtle's `position`, `degrees`, `isPenDown` status, colors, and line widths).\n- As `TurtlePainter` iterates through the instructions, each instruction executes against the `PaintContext`, mutating the state and calling raw `Canvas` drawing methods.\n\n### 4. Animation Mechanism\n\n`AnimatedTurtleView` leverages Flutter's `AnimationController` and `AnimatedBuilder`. When built, it calculates the total number of compiled instructions. As the animation progresses from `0.0` to `1.0`, the widget progressively passes a growing sublist of instructions (e.g., from index `0` to `total_instructions * animation.value`) to the `TurtlePainter`. This simple yet effective approach smoothly simulates real-time drawing without requiring complex frame-by-frame state serialization.\n\n## Flutter Turtle DSL\n\nIf you have Logo code like this:\n\n```logo\nrepeat 5 [ fd 100 rt 144 ]\n```\n\nThe equivalent code in the Flutter Turtle DSL would be:\n\n```dart\n[\n  Repeat((_) =\u003e 5, [\n    Forward((_) =\u003e 200),\n    Right((_) =\u003e 144),\n  ]),\n];\n```\n\n### Flow control\n\nFlow control commands are evaluated dynamically during compilation. You can use the `IfElse` class just like an `if...else` statement in Dart, and the `Repeat` class for loops.\n\nAn example of `IfElse`:\n\n```dart\n// If the condition evaluates to true, move forward; otherwise, move backward.\nIfElse((_) =\u003e true, [Forward((_) =\u003e 10.0)], [Back(() =\u003e 10.0)]),\n```\n\nAn example of `Repeat`:\n\n```dart\n// Repeat the inner commands 10 times.\nRepeat((_) =\u003e 10, [Forward((_) =\u003e 10.0)]),\n```\n\n### Macros\n\nWhile the DSL does not support traditional named functions natively, you can achieve reusable components using macros. Use the `SetMacro` command to register a parameterized block of commands:\n\n```dart\nSetMacro('macro', [Forward((_) =\u003e 10.0)]), // Registers a new macro named \"macro\".\n```\n\nYou can then execute the macro dynamically using the `RunMacro` command:\n\n```dart\nRunMacro('macro', (_) =\u003e {'arg1': 'value1', 'arg2': 'value2'}),\n```\n\nYou can pass arguments when calling a macro. These arguments are provided as a Dart `Map` and are accessible via the callback parameter `_` to every command within the macro. For example:\n\n```dart\nSetMacro('macro', [Forward((_) =\u003e _['arg1'])]), // Uses the \"arg1\" value from the arguments map.\nRunMacro('macro', (_) =\u003e {'arg1': 10.0}),\n```\n\n## Supported Commands\n\nThe currently supported primitives and logic structures include:\n\n### Turtle motion \u0026 Styling\n\n- `PenDown`\n- `PenUp`\n- `Left`\n- `Right`\n- `Forward`\n- `Back`\n- `SetColor`\n- `SetStrokeWidth`\n- `GoTo`\n- `ResetPosition`\n- `ResetHeading`\n- `Label`\n- `SetLabelHeight`\n\n### Flow control\n\n- `If`\n- `IfElse`\n- `Repeat`\n\n### Macros\n\n- `SetMacro`\n- `RunMacro`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzonble%2Fflutter_turtle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzonble%2Fflutter_turtle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzonble%2Fflutter_turtle/lists"}