Install Asset
Install via Godot
To maintain one source of truth, Godot Asset Library is just a mirror of the old asset library so you can download directly on Godot via the integrated asset library browser









Quick Information

Scalable Vector Shapes 2D lets you do 3 things:- Draw seamless vector shapes using a Path Editor inspired by the awesome Inkscape- Animate curves of your vector shapes (useful for faces, whips, dents in cans)- Import .svg files as seamless vector shapes in stead of as raster images⚠️Important:If you are updating* you may need to reload your project once for the plugin to work again, due to some renamed components.* The safest way to update this plugin is to:1. Save and close all your open scenes2. Disable the plugin via `Project > Project Settings > Plugins`3. Close your project (quit to project list)4. Download the stable zip from github: https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/archive/refs/tags/2.16.0.zip 5. Fully replace `res://addons/curved-lines2d` with the same directory in the zip file6. Open your project again and enable again via `Project > Project Settings > Plugins`7. If you see errors, just click on: `Project > Reload Current Project`⚠️Report bugs!Spotted a bug? Help me fix it quickly by reporting it on github:https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/issuesWatch a 10 minute A-Z explainer on youtube:https://www.youtube.com/watch?v=_QOnMRrlIMkLook at some new features added since then on youtube:https://youtu.be/pP0CYEvU2uQ?feature=sharedInspired by Mark Hedberg's great explainer:https://www.hedberggames.com/blog/rendering-curves-in-godotOr ask a question on the subreddit:https://www.reddit.com/r/ScalableVectorShape2DBuy me a coffee:https://buymeacoffee.com/rvanderarkp# Changelog## 2.16.0### Added- Uniform transformation buttons (move/rotate/scale all points without changing `Node2D.transform`)- The `spin` property to represent a Rectangle / Ellipse primitive's local rotation.### Changed- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_ellipse_points`- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_rect_points`## 2.15.0### Added- Auto-scaling for SVG image icons on GUI controls (`Button`, `TextureButton`, `TextureRect`) using `SVGTextureHelper` (thank you to @kcfresh53)### Changed- Dropped class_names from GUI items in plugin itself to prevent cluttering up developers' `add node` dialog## 2.14.3### Added- Bake Animation as Sprite Frames (under Advanced Editing tab) as a PNG spritesheet, or separate PNG files.- Video explainer tab with some youtube links- Center 2D viewport around newly created shapes...- ...and around newly imported SVG Files### Changed- Bugfix: pause animation player before snapshotting sprite frame (from 2.14.0)- Bugfix: svg importer must await first render frame before baking when not importing as `ScalableVectorShape2D`## 2.13.4### Changed- Bugfix: race conditions due to unsafe pass by reference when setting `Polygon2D.polygon` in combination with `Polygon2D.polygons`- Performance tweak: no more unnecessary invocations of `Geometry2DUtil.calculate_poly_strokes`## 2.13.3### Added- New node type `AdaptableVectorShape3D` of which the shape can be changed via an assigned `ScalableVectorShape2D`- New form `Curve Settings` added under tab `Project Settings`### Changed- Bugfix: svg importer now positions clip-paths correctly by using the same parent (`<g>`-node) as the clipped shape- Bugfix: calculate polygons at max once per frame (major performance fix for animations)- Adds tab `Project Settings`- Moves `Editor Settings` to tab `Project Settings`- Flags property `update_curve_at_runtime` on by default (changeable in `Curve Settings`)- Flags property `resource_local_to_scene` on by default (changeable in `Curve Settings`)## 2.13.0 - 2025-08-28### Added- Advanced tab in bottom panel with 3 export buttons usable on any type of selected node: PNG, Baked, 3D Scene- Export as 3D scene (all Fills and Strokes are turned into `CSGPolygon2D` instances)### Changed- Bugfix: removed infinite recursion when exporting a scene root as 'Baked Scene'## 2.12.3 - 2025-08-23### Added- You can now also use Polygon2D for Strokes using the `poly_stroke` property- Collision Objects will now also get `CollisionPolygon2D`s for strokes- Adds `signal polygons_updated(polygons: Array[PackedVector2Array], poly_strokes: Array[PackedVector2Array], self_ref : ScalableVectorShape2D)`### Changed- Reverts hiding of the Collision Polygon property field- Fix: position of new shapes is now always Vector2.ZERO- In the Stroke Inspector plugin, stroke properties are now edited on `ScalableVectorShape2D` in stead of its assigned `Line2D`: - `line.default_color` -> `stroke_color` - `line.width` -> `stroke_width` - `line.begin_cap_mode` -> `begin_cap_mode` - `line.end_cap_mode` -> `end_cap_mode` - `line.joint_mode` -> `line_joint_mode`- ⚠️ Please note that keyframes for all these properties are now set on `ScalableVectorShape2D` directly in stead of the assigned `Line2D`- Fix edge cases where holes resulting from geometry operations are not handled correctly- Rat's return example uses new signal to allow all blocks sharing the same `StaticBody2D`## 2.11.5 - 2025-18-08### Added- Snap to pixel when adding points- Snap to pixel when dragging curve edges- Snap to pixel when dragging gradient stops- Snap to pixel when changing rx/ry and size of primitive shapes### Changed- Export as 'baked' scene now supports cutouts, clips and merged shapes- Import SVG as Node2D in stead of ScalableVectorShape2D now works with cutouts, clips and merged shapes- Export buttons moved to inspector group `ScalableVectorShape2D > Export Options` to save screen real-estate## 2.11.3 - 2025-14-08### Added- SVG Importer now supports `<clipPath>`, `<use>` and embedded base64 encoded `<image>` (results may vary)### Changed- Use Pascal case in stead of Camel case to represent imported svg file names- Rename dock nodes in order to reference them with unique name## 2.11.2 - 2025-10-08### Added- Shortcut `Ctrl+Shift+Mousewheel` to pick cutout shape- Shortcut `Ctrl+Shift+Right click` to change clipping operation- 'Rat's return' (examples/rats_return.tscn) to illustrate shape manipulation programmatically- `Export as baked scene` button.- Flag `use_union_in_stead_of_clipping` to `ScalableVectorShape2D` which turns a cutout into a merged shape- Convenience method `clipped_polygon_has_point(global_pos : Vector2)` to detect clicks __on__ a shape without the click being in a hole- A bubbly cloud example to illustrate `use_union_in_stead_of_clipping`### Changed- Separates out the calculation of outlines and fixes most issues with it (holes within holes not working yet)- Can now cut holes in ellipses using right click in the add shapes programatically example.## 2.11.0 - 2025-06-08### Added- Preparations for svg clipPath support by adding flag `use_intersect_when_clipping` to `ScalableVectorShape2D` which turns a cutout into a clip_path by invoking `Geometry2D.intersect_polygons(...)` in stead of `Geometry2D.clip_polygons(...)`### Changed- Bugfix: svg importer can now also use gradients defined _after_ the element referring to it via `href`## 2.10.4 - 2025-06-08### Added- Mac users can now use the Cmd key in stead of Ctrl key### Changed- Bugfix: SVG importer can now handle rgb() and rgba() colors for stroke and fill- Bugfix: Style attribute of root element not is ignored anymore- SVG importer evaluates all cutouts for a shape at once- ScalableVectorShape2D caches outlines after tessellate and only reinvokes tessellate when the curve actually changes- Only recalculate curve when local transform of cutout changes (cutout has to be direct child of parent for this to trigger correctly)- Prevent global position form from being visible when plugin is enabled- Bugfix: order of undo/redo operations fixed for dragging operations## 2.10.2 - 2025-02-08### Added- You can now import an SVG file into any type of opened scene (3D, GUI, Node)- You can now create a new ScalableVectorShape2D in any type of opened scene### Changed- Using uniqe names in stead of `find_node` to refer to tool controls- SVG importer only creates cutout when initial point of follow-up path is _inside_ first shape- Bugfix: svg transform attribute now supports multiple transform commands- Bugfix: can now perform svg transform translate(...) with one parameter as well as two- Bugfix: resets the cursor position of follow-up paths correcty now (after the z/Z command)- Bugfix: SVG importer sets rx/ry values compliantly now## 2.9.2 - 2025-31-07- Added pinball starter example in examples dir## 2.9.1 - 2025-27-07### Added- Use Ctrl+Shift+Left click to create a cutout shape for the selected shape- One shape can have multiple cutout shapes assigned (via the `clip_paths` property)- Cutouts can be holes, made possible by multiple polygons- Cutouts are `ScalableVectorShape2D` nodes themselves with all the same capabilities- A `NavigationRegion2D` can now be assigned via the `navigation_region` property- The SVG importer now also supports cutout paths within the `d="..."` attribute (results may vary)## 2.8.2 - 2025-21-07### Added- The `collision_object` property is meant to replace the `collision_polygon` property- This will hold an assignment to a descendant of `CollisionObject2D` (`Area2D`, `StaticBody2D`, etcetera)- This managed `CollisionObject2D` will get directly generated `Polygon2D` children from the plugin### Changed- The `collision_polygon` property is now marked as deprecated (but will function the same for backward compatibility)- Bugfix: fixed parsing bug for quadratic bézier curves### Removed- Removed the assignment inspector form field for the `collision_polygon` property once it has been unassigned## 2.7.1 - 2025-16-07### Added- Add direct arc support for ScalableVectorShape2D: moving arcs around is now much easier by replacing many points by just the 2 (start and end)- The arcs can be dynamically manipulated via metadata fields (radius, rotation, large arc, sweep -> see: [svg specification](https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands))- The arcs can also be animated using the `Curve Settings > Batch insert` button for key frames### Changed- Bugfix: fixed index out of bounds for scale-transform in svg importer.- Removed `Rat` class_name from the rat example to prevent name conflicts.## 2.6.6 - 2025-11-07## Changed- Bugfix: SVG importer can now handle negative numbers without leading whitespace- Bugfix: SVG importer now handles multiple shapes in one svg path element## 2.6.5 - 2025-10-07### Added- SVG importer now supports the arc command (fixed at 4 degree angles for now)## 2.6.4 - 2025-01-07### Changed- ScalableVectorShape2D nodes can only be selected when mousedown and mouseup event registered on the same node ('click'-event)- ScalableVectorShape2D nodes can now only be selected when they are visible- ScalableVectorShape2D nodes can not be selected anymore when they are locked using the lock-icon- ScalableVectorShape2D nodes can not be selected anymore when they are part of a different scene## 2.6.3 - 2025-06-15### Added- Change line-capping of strokes via inspector- Change line-joining of strokes via inspector- Pick default line-cap and line-join modes for creating new strokes- Maps line-join modes and line-cap modes from SVG to Godot using the importer- Pixel snap mode checkbox, disabled by default- Show point positions under editor hints- Form to set exact global position for curve point and handles (in path mode)- Export as PNG button in inspector form of ScalableVectorShape2D### Changed- "Show point numbers" renamed to "Show point details", also toggles position info on/off- Bugfix: build failures due to internal tool class referenced at runtime## 2.5.2 - 2025-06-08### Added- Makes Rectangles editable using one size handle and two rounded corner handles- Makes Ellipses editable using one size handle- Adds create buttons for Rectangle as Rectangle and Ellipse as Ellipse- ..next to exists create buttons for them as Path- Adds a "convert to path" button in the inspector when `shape_type` is a rectangle or ellipse### Changed- Enhancement: newly created Rectangle has its origin at its natural center, in stead of its top/left corner- Bugfix: gradient stop color order stays in tact after undo remove- Bugfix: Bottom Panel is more visible after fresh install- Bugfix: preloading replaced by loading to fix busy resource issues in inspector plugin code- Bugfix: previewed shape has scaled stroke### Removed- Custom collapse / expand titles from inspector plugin forms in favour of `@export_group` annotations on `ScalableVectorShape2D`## 2.4.3 - 2025-06-07### Changed- Fixed a preloading + busy device bug in inspector plugin load script## 2.4.2 - 2025-06-05### Added- Batch insert key frame button for entire curve- Batch insert key frame button for entire gradient- Key frame button for stroke width- Key frame button for fill stroke color- Key frame button for fill color### Changed- Fixes ordering bug of gradient stop color buttons- Reconnects import svg button to file dialog in svg importer panel## 2.3.2 - 2025-05-31### Added- Adds gradient fill toggle to the inspector form- Adds gradient stop color buttons to the inspector form- Adds gradient start- and end handle to 2D editor- Adds stop color handles to 2D editor- Implements paint-order correctly in SVG importer- Better tooltips for SVG importer- Warning message for unsupported clipping (using 'm'- / 'M'-operator) in SVG importer### Changed- Bugfix: resizes the gradient texture when the bounding box changes- Regression fix: all the SVG importer settings in the SVG importer form work again## 2.2.1 - 2025-05-28### Added- Adds easier to use forms for Stroke, Fill and Collision shape to the `ScalableVectorShape2D` inspector- Adds project settings for defaults like stroke width, stroke and fill colors, and paint order- Separates the point numbers from the hint labels- Saves project settings for enabling and disabling hints and viewport editing- Shows a preview of the shape which is about to be added via the bottom panel- Explanatory tooltips for all the fields and options that are not self-explanatory enough## 2.1.3 - 2025-05-24### Added- Undo/Redo for strokes (`Line2D`) fills (`Polygon2D`) and collisions (`CollisionPolygon2D`) added with the `Generate` button in the inspector- After Undo of creating a new shape from the bottom panel, its parent node is automatically selected again- Resize a shape without using the `scale` property using `Shift+mousewheel`, for more pixel perfect alignment### Changed- Fix: after adding point on line with double click, the correct point is removed again with undo- Fix: when a curve is closed, it stroke (the `Line2D` assigned to the `line`-property) is also closed and vice-versa- Fix: closing a shape now works by simply adding a segment between the last and first point## 2.1.0 - 2025-05-21### Added- Use `Ctrl+click` to add points to a shape faster- Undo/Redo support for shapes from the bottom panel### Changed- Shapes from the bottom panel are added as child of the selected node- When no node is selected, shapes from the bottom panel are added in the center of the viewport- Batched Undo/Redo for all mouse drag operations- Tooltip and ability to copy link with right click on `LinkButton` to external content## 2.0.0 - 2025-05-19### Added- Custom node `ScalableVectorShape2D` introduced, enabling editing of its `Curve2D` using the mouse similar to the popular open source vector drawing program [Inkscape](https://inkscape.org/)- Add a circle, ellipse or rectangle from the bottom panel directly- Ability to Undo/Redo many drawing operations- A more comprehensive manual in the [README](./README.md)### Changed- The custom node `DrawablePath2D` was deprecated in favor of `ScalableVectorShape2D`## 1.3.0 - 2025-05-10_Last stable release of EZ Curved Lines 2D_This shipped 2 things:- An SVG file importer, which transforms shapes into native Godot nodes- The custom node `DrawablePath2D`, which extends from Godot's `Path2D` to use its built-in `Curve2D` editor
Scalable Vector Shapes 2D plugin for Godot 4.4
Scalable Vector Shapes 2D lets you do 3 things:
- Draw seamless vector shapes using a Path Editor inspired by the awesome Inkscape with a new node type:
ScalableVectorShape2D
[^1] - Animate the shape of the curve using keyframes on a property-track in an
AnimationPlayer
- Import .svg files as seamless vector shapes in stead of as raster images[^2]
[^2]: Important sidenote: This plugin only supports a small - yet relevant - subset of the huge SVG Specification
Watch the A-Z explainer on Youtube
In this 10 minute video I explain how to use all the features of Scalable Vector Shapes 2D in short succession:
[^1]: Looking for EZ Curved Lines 2D? The renamed plugin deprecates the old DrawablePath2D
custom node in favor of ScalableVectorShape2D
. A Conversion button is provided: converter button. The reason is that ScalableVectorShape2D
inherits directly from Node2D
giving much more control to the plugin over how you can draw.
Table of Contents
- Scalable Vector Shapes 2D plugin for Godot 4.4
- Table of Contents
- Drawing Shapes in the Godot 2D Viewport
- The Create Shapes Dock
- The Import SVG File Dock
- The Project Settings Dock
- The Advanced Tab
- Manipulating shapes
- Adding a point to a shape
- Bending a curve
- Creating, mirroring and dragging control point handles
- Closing the loop and breaking the loop
- Deleting points and control points
- Setting the global position of a point / curve handle manually
- Create a cutout/clip/merge shape (a hole, a clipped frame, ...)
- Converting a line segment into an arc-segment
- Editing arc properties
- Setting the pivot of your shape
- Manipulating 2D Shapes in the 3D export
- Manipulating gradients
- Using the Inspector Form for
ScalableVectorShape2D
- More about assigned
Line2D
,Polygon2D
andCollisionObject2D
- Animating / Changing shapes at runtime
- FAQ's
- The curve of my
ScalableVectorShape2D
won't animate at runtime, what do I do? - I want to change shapes while debugging my game. Is this even possible?
- When I animate the curve of an imported scene, it animates all the other curves as well
- When I duplicate a
ScalableVectorShape2D
and change its shape, the originalScalableVectorShape2D
shape also changes - Can I draw shapes programmatically?
- Should I draw shapes programmatically?
- When should I draw shapes programmatically?
- Can I change shapes in the 2D editor while running the game?
- The curve of my
- Attributions
- Reaching out / Contributing
Drawing Shapes in the Godot 2D Viewport
Basic Drawing Explainer on youtube
Quick Start
After activating this plugin a new bottom panel item appears, called "Scalable Vector Shapes 2D".
There are 2 recommended ways to start drawing:
- Creating a Circle/Ellipse, Rectangle or empty Path using the bottom panel item
- Using the
.svg
importer
The Create Shapes Dock
The Create Shapes
tab gives you some basic choices:
Creating Paths based on Bézier curves
Pressing the Create Empty Path
or one of the Create Path
buttons will add a new shape to an open 2D Scene
in 'Path' mode, meaning all points in the 'Bézier' curve are editable.
Creating 'primitive' shapes: Rectangle and Ellipse
It's probably easier to start out with a basic primitive shape (like you would in Inkscape <3) using the Create Rectangle
or Create Ellipse
button. This will expose less features, but will make it a lot easier to manipulate shapes:
Ellipses will only have one handle to change the size
property with (representing the x and y diameter). This will set the rx
and ry
property indirectly.
Rectangles will have a handle for size
and 2 handles for rounded corners rx
and ry
property.
Draw Settings
- Enable/Disable Fill (when creating new shapes via this bottom panel)
- Fill color (when creating new shapes in this bottom panel)
- Enable/Disable Stroke (when creating new shapes this this bottom panel)
- Stroke color (when creating new shapes in this bottom panel)
- Choose a
CollisionObject2D
type (when creating new shapes in this bottom panel, default is no collision object assignment) - Paint order: a toggle which represent what comes in front of what (when creating new shapes in the bottom panel)
- Stroke Settings:
- Stroke Width (when creating new shapes via this bottom panel)
- Use
Line2D
: when flagged off, aPolygon2D
will be used to draw strokes with in stead (see also:Line2D Stroke
versusPolygon2D Stroke
) - Begin- and End Cap modes
- Line Joint Mode
Futher reading
Read more about manipulating shapes
The Import SVG File Dock
Watch an explainer on Youtube
Using the Import SVG File Dock
On the left side of this panel is a form with a couple of options:
- Import as ScalableVectorShape2D: check this Off if you want to import the svg file with only built-in godot nodes, without being able to edit/animate the curves in the editor.
- Lock imported shapes in editor: this simply flags on the lock so that the
Polygon2D
,Line2D
, etc are not selected on click, but the owning ScalableVectorShape2D is - Flag on antialiased on Polygon2D and Line2D: flags on the
antialiased
property of either - Use Line2D for Strokes: when flagged Off a
Polygon2D
is used for strokes in stead of a Line2D - Pick a
CollisionObject2D
type to also generate collision polygons when importing the svg file
Line2D
Stroke versus Polygon2D
Stroke
A tooltip highlights the costs and benefits when picking either of these to draw strokes with:
- A
Polygon2D
stroke can be more neatly clipped than aLine2D
CollisionPolygon2D
's matchPolygon2D
Stroke better- A
Polygon2D
stroke can be textured with gradients like fills are textured Line2D
has sharper caps and line joints at high zoomLine2D
can be textured directionally in stead of like a Fill textureLine2D
can set different Begin and End Cap Modes wherePolygon2D
can only pick one
The import log
On the right side is an import log, which will show warnings of known problems, usually unsupported stuff.
The link it shows is to the issues list on the github repository hosting this plugin. Here you can report any encountered bugs while importing SVG files using this plugin.
The Project Settings Dock
Editor Settings (how the 2D Viewport should behave):
- Enable/Disable ScalableVectorShape2D Editing (when checked off, you can edit nodes the normal, built-in, godot-way. You are going to need this)
- Show/Hide Edit hints
- Show Point Details (which are the exact indices of each point on the
Curve2D
of this shape, what is it's global position) - Snap to Pixel (snaps points and curve handles to whole pixels on the global transform)
- Snap distance (the snap step / resolution)
Curve Settings
These settings are applied to the Curve Settings
of new shapes when added via the bottom panel docks (either SVG importer or via Create Shapes).
For more information on these settings, please refer to the section on The Curve settings inspector form
The Advanced Tab
Since release 2.13.0
a tab named 'Advanced' is added to the bottom dock.
Basic export options
- PNG file (see Export as PNG Button )
- A 'Baked' scene (see Export as 'baked' scene button)
- 3D scene: creates a new 3D scene, in which all the Fills and Strokes in the scene are turned into instances of
CSGPolygon3D
[^6]
[^6]: Coming soon: a 3D Node with an editable outline using a ScalableVectorShape2D
node
Bake Animations
Since 2.14.0
you can export your animated scene as sprite frames in one PNG spritesheet or separate PNG files.
Manipulating shapes
The hints in the 2D viewport should have you covered, but this section lists all the operations available to you. You can also watch the chapter on sculpting paths on youtube:
Adding a point to a shape
Using Ctrl
[^5] + Left Click
you can add a point anywhere in the 2D viewport, while your shape is selected.
[^5]: Use Cmd
in stead of Ctrl
on a mac
By double clicking on a line segment you can add a point inbetween 2 existing points:
Bending a curve
Holding the mouse over line segment you can start dragging it to turn it into a curve.
Creating, mirroring and dragging control point handles
When you have new node you can drag out curve manipulation control points while holding the Shift
button. The 2 control points will be mirrored for a symmetrical / round effect.
Dragging control point handles while holding Shift
will keep them mirrored / round:
Dragging them without holding shift will allow for unmirrored / shap corners:
Closing the loop and breaking the loop
Double clicking on the start node, or end node of an unclosed shape will close the loop.
Double clicking on the start-/endpoint again will break the loop back up:
You can recognise the start-/endpoint(s) by the infinity symbol: ∞
Deleting points and control points
You can delete points and control points by using right click.
Setting the global position of a point / curve handle manually
Using Alt+Click
you can now open a form to set the global position of a point manually:
Create a cutout/clip/merge shape (a hole, a clipped frame, ...)
While holding Ctrl+Shift
[^5] on a selected shape you can start adding cutouts to your selected shape:
- Use
mousewheel
to change shapes (rectangle, ellipse, or empty path) - Use
right click
to change operation (cut out, clip, or merge) - Use
left click
on your selected shape to create and select the newScalableVectorShape2D
which acta as a cutout, a frame clipping, or merged shape:
Cutting out an empty shape
When cutting out an empty shapem, the created cutout will have only one point, so to see the effect you'd need to add more points to using regular Ctrl+Click
[^5]:
Converting a line segment into an arc-segment
Use Right click
on a line segment to convert it into an arc[^3] (a an ellipse-shaped bend with an x- and y-radius).
Use Right click
on an arc again to convert it back into a normal line segment.
Editing arc properties
Using Left click
on an arc segment opens a popup form to edit the properties of the arc:
- radius (
rx
/ry
) - rotation (rotates the arc around its elliptical center; is only noticable when radius is non-uniform)
- large arc (when the arc's radius is greater than distance between its start- and endpoint it can be drawn the short and the long way 'round)
- sweep (determines the direction the arc points are drawn: clockwise / counter-clockwise; this effectively flips the arc)
[^3]: Arcs are implemented the same way as specified by the w3c for scalable vecor graphics.
Setting the pivot of your shape
You can use the Change pivot
mode to change the origin of your shape, just like you would a Sprite2D
. In this case, the 'pivot' will actually be the position
property of you ScalableVectorShape2D
node.
This rat will want to rotate it's head elsewhere:
Like this:
Manipulating 2D Shapes in the 3D export
Using the new Export to 3D Scene
in the Advanced Editing Tab produces the new AdaptableVectorShape3D
node, which holds instances of CSGPolygon3D
with:
Pressing the button Add 2D Shape Editor
will instantiate a new ScalableVectorShape2D
that can be used to edit with. For now I will suffice with a screenshot. I'm hope to record a long explainer about this soon.
This screenshot was made using the DualEditor plugin by @Meta-Ben, which is very useful for this purpose:
Animating 3D curves
You can also use the Batch insert
button for curve key frames to animate the 3D shape's curve. Of course the performace impact for this is not negligable.
Manipulating gradients
Once a gradient is assigned to the 'Fill' of your shape via the inspector, its properties can be changed using the same controls as will the other handles.
Changing the start- and endpoint of the gradient
Drag the outer orbit of the start- and endpoint of a the gradient line using the left mouse button to move them:
Changing the color stop positions
Drag the color stops along the gradient line to change their position.
Right click to remove a color stop.
Add new color stops
Double clicking on the gradient line will add a new color stop (the assigned color will be sampled from the existing color at that point)
Ways to prevent 'over-selecting' ScalableVectorShape2D
nodes
This plugin can sometimes get in the way of the default 2D viewport behavior. Sometimes it is hard not to select a ScalableVectorShape2D
.
There are 4 ways to get around this:
- Locking the
ScalableVectorShape2D
using the lock togglebutton above the 2D viewport
- Hiding the
ScalableVectorShape2D
via the scene tree - Saving the branch containing the
ScalableVectorShape2D
as a new scene via the scene tree and importing it will also prevent selection - Toggling off Enable/Disable ScalableVectorShape2D Editing altogether in the bottom panel
Using the Inspector Form for ScalableVectorShape2D
The following custom forms were added, with extensive tooltips to help explain the actual functions they provide:
- Fill (actually the assigned
Polygon2D
) - Stroke (actually the assigned
Line2D
orPolygon2D
) - Collision (manages an assigned
CollisionObject2D
) - Navigation (manages an assigned
NavigationRegion2D
) - Curve Settings
- Masking
- Shape Type Settings
- Editor Settings
- Export Options
Inspector Form
Convert to Path button
When a primitive shape (basic rectangle or ellipse) is selected, a Convert to Path
-button is available at the top of the inspector.
The Fill inspector form
When the selected shape has no fill, an Add Fill
button is provided. Clicking that will create and assign a new Polygon2D
to the selected ScalableVectorShape2D
:
Once assigned, the following options are available:
- Fill color, changes the
color
property of the assignedPolygon2D
- Gradient, will assign or remove a
GradientTexture2D
to thePolygon2D
- Stop colors (if a gradient is set), one color button per color
- A
Edit Polygon2D
button, which will make the editor select the assignedPolygon2D
Below that, a standard godot Assign ...
-field is also available to set the polygon
-property directly with and to enable unassignment.
The Stroke inspector form
With this form the following ScalableVectorShape2D
properties can be edited:
stroke_color
stroke_width
begin_cap_mode
(in case of aPolygon2D
-based stroke, this will also set the end cap)end_cap_mode
line_joint_mode
When a Line2D
is assigned to draw the stroke with, these properties will be kept synchronized with the ScalableVectorShape2D
properties.
In case of a Polygon2D
based stroke, the stroke_color
will be kept synchronized with the Polygon2D
color.
Creating new Strokes
When the selected shape has no stroke, an extra set of buttons is provided:
Add Line2D Stroke
Add Polygon2D Stroke
Clicking either will create and assign a new Line2D
or Polygon2D
to the selected ScalableVectorShape2D
:
Below that, a standard godot Assign ...
-field is also available to set these properties:
line
: aLine2D
assignmentpoly_stroke
: aPolygon2D
assignment
The Collision inspector form
This works the same as the Fill- and Stroke forms, but in this case a descendant of a CollisionObject2D
is assigned to the collision_object
-property[^4]:
[^4]: Note that the collision_polygon
property of ScalableVectorShape2D
remains supported for backward compatibility, even though the inspector form will now show a deprecation warning and suggest replacing it by assigning a CollisionObject2D
to the collision_object
property.
Every time the shape is changed, one or more Polygon2D
nodes will be added/updated as direct children of this collision_object
. The descendants of CollisionObject2D
are:
StaticBody2D
Area2D
AnimatableBody2D
RigidBody2D
CharacterBody2D
PhysicalBone2D
The Navigation inspector form
This form can hold a reference to an assigned NavigationRegion2D
. When the shape changes, a new navigation polygon is calculated.
The Curve settings inspector form
The curve settings inspector form provides the following options
- A
Batch insert
keyframes button for all theCurve2D
's control points (the whole shape). This will be active when a valid track is being edited in aAnimationPlayer
via the bottom panel - The standard godot built-in editor for
Curve2D
resources, assigned to thecurve
property of the selectedScalableVectorShape2D
- The
update_curve_at_runtime
checkbox, which enables animating the entire shape - The
max_stages
property which influences smoothness (and performance!) of curve drawing; a higher value means smoother lines - The
tolerance_degrees
property, which also influences smoothness (and performance) of curve drawing: a lower value adds a smoother curve, especially for very subtle bends - The
arc_list
property: a container for the metadata-objects describing elliptical arc segments of the curve (implemented viaScalableArc2D
andScalableArcList
resource-classes).
The Masking Inspector form
These properties are used for clipping this shape and cutting out of this shape.
- The
clip_paths
property: an array of assignedScalableVectorShape2D
-nodes, which describe the shapes to cut out of this shape - When the
use_interect_when_clipping
property is checked on and thisScalableVectorShape2D
is used in another's clip_paths array, theGeometry2D.intersect_polygons(...)
operation is used in stead of theGeometry2D.clip_polygons(...) operation
- When the
use_union_in_stead_of_clipping
property is check on and thisScalableVectorShape2D
is used in another's clip_paths array, theGeometry2D.merge_polygons(...)
operation is used in stead of theGeometry2D.clip_polygons(...) operation
[^8]
[^8]: see also: the cloud example
The Shape type inspector form
This form allows manipulation of the properties of primitive shape types (rectangle, ellipsis):
- Shape type, here you can selected the type of the shape: Path, Rect and Ellipse. (Be warned: changing a shape from a path to a primitive shape is a destructive action and cannot be undone)
- Offset: this represents the position of the pivot relative to the shape's natural center.
- Size: the box size of the entire shape (stroke thickness excluded)
- Rx: the x-radius of the shape
- Ry: the y-radius of the shape
It is best to change these properties via the handles in the 2D editor. They are, however, quite useful for animating key frames.
The Editor settings inspector form
This form exposes 2 settings:
- Shape Hint Color: the color of the line with which this shape is drawn, when selected
- Lock Assigned Shapes: when this is checked, added strokes, fills and collision polygons will be locked in the editor, once created.
The Export Options inspector form
Export as PNG button
With the Export as PNG
-button you can save any ScalableVectorShape2D
and its children as a new .png
-file. Note that nodes which are assigned as Fill or Stroke that are higher up in the hierarchy will be excluded from the exported file.
You can however change the type of any Node2D
to ScalableVectorShape2D
temporarily in order to export group of shapes as a PNG file.
Export as 'baked' scene button
With the Export as baked scene
button you can generate a new scene (like Save branch as scene
), with all the ScalableVectorShape2D
-nodes converted to basic Node2D
-nodes.
Use this when you are done drawing entirely and do not want to update curves at runtime, or when you want to keep the shapes but drop the dependency of this plugin from your project.
Caveats when 'Baking'
An exported AnimationPlayer will not support animated curves, track references will, however, remain.
More about assigned Line2D
, Polygon2D
and CollisionObject2D
Using the Add ...
buttons in the inspector simply adds a new node as a child to ScalableVectorShape2D
but it does not need to be a child. The important bit is that the new node is assigned to it via its properties: polygon
, line
and collision_object
.
Watch the chapter about working with collisions, paint order and the node hierarchy on youtube
This video gives more context on how Line2D
, Polygon2D
and CollisionPolygon2D
are assigned to the ScalableVectorShape2D
:
Animating / Changing shapes at runtime
Youtube explainer on animating
Watch this explainer on youtube on animating:
A note up front (this being said)
The shapes you create will work fine with basic key-frame operations.
You can even detach the Line2D, Polygon2D and CollisionObject2D from ScalableVectorShape2D
entirely, once you're done drawing and aligning, and change the ScalableVectorShape2D
to a simple Node2D
if necessary.
Animating the shape and gradients at Runtime
Sometimes, however, you want your shape to change at runtime (or even your collision shape!)
You can use the Update Curve at Runtime
checkbox in the inspector to enable dynamic changing of your curved shapes at runtime.
Add keyframes in an animation player
You can then add an AnimationPlayer
node to your scene, create a new animation and (batch) insert key frames for the following:
- The entire shape of your
ScalableVectorShape2D
, which are:curve:point_*/position
curve:point_*/in
curve:point_*/out
arc_list:arc_*/radius
arc_list:arc_*/rotation_deg
arc_list:arc_*/large_arc_flag
arc_list:arc_*/sweep_flag
- All the gradient properties of your fill (
Polygon2D
assigned toScalableVectorShape2D
), which are:texture:gradient:colors
(the entirePackedColorArray
)texture:gradient:offsets
(the entirePackedFloat32Array
)texture:fill_from
texture:fill_to
- Fill color, i.e.: the
color
of the assignedPolygon2D
* Note: the keyframes of stroke properties are set directly on ScalableVectorShape2D
as of release 2.12
Don't duplicate ScalableVectorShape2D
, use the path_changed
signal in stead
When the update_curve_at_runtime
property is checked, every time the curve changes in your game the path_changed
signal is emitted.
Duplicating a ScalableVectorShape2D
will not make a new Curve2D
, but use a reference. This means line-segments will be calculated multiple times on one and the same curve! Very wasteful.
If however you want to, for instance, animate 100 blades of grass, just use one ScalableVectorShape2D
and have the 100 Line2D
node listen to the path_changed
signal and overwrite their points
property with the PackedVector2Array
argument of your listener func
:
This very short section of the youtube video illustrates how to do this: https://youtu.be/IwS2Rf65i18?feature=shared&t=55
Performance impact
Animating curve points at runtime does, however, impact performance of your game, because calculating segments is an expensive operation.
Under Tesselation settings
you can lower Max Stages
or bump up Tolerance Degrees
to reduce curve smoothness and increase performance (and vice-versa)
FAQ's
The curve of my ScalableVectorShape2D
won't animate at runtime, what do I do?
Check the box:
I want to change shapes while debugging my game. Is this even possible?
Yes, when you check the box Update Curve at Runtime
box.
When I animate the curve of an imported scene, it animates all the other curves as well
This is a common issue: there is one Curve2D
instance being referenced by all scenes. You fix this by checking On "Local To Scene" for the Curve2D
:
When I duplicate a ScalableVectorShape2D
and change its shape, the original ScalableVectorShape2D
shape also changes
This is a common issue: there is one Curve2D
instance being referenced by both nodes. At the moment there is not a quick fix, but you can always follow these steps:
- Right click on your copy in the scene tree
- Pick "Save branch as Scene"
- Make the
Curve2D
"Local to Scene" like in the previous faq example
Can I draw shapes programmatically?
Yes you can. There are a couple of small things to be aware of:
- You need to set
my_shape.up_date_curve_at_runtime = true
- To draw anything, your shape needs a Stroke, Fill, or Collision Object:
- Setting a stroke:
my_shape.line = Line2D.new()
- Setting a fill:
my_shape.polygon = Polygon2D.new()
- Setting a collision object:
my_shape.collision_object = StaticBody2D.new()
- The Stroke, Fill, Collision Object need to be inside the scene tree, i.e.:
my_shape.add_child(my_shape.line)
I added a small example based on this question
Should I draw shapes programmatically?
This depends on the complexity of what you want to achieve.
In many cases just drawing something in the editor and saving it as a scene to import elsewhere (or instantiate()
via preloading) is a better option, adhering to the Keep it Simple principle.
But that's just my personal opinion.
When should I draw shapes programmatically?
There are very many situations left where you might want to do exactly this, but that is up to your own creativity.
One powerful feature I can think of is 'mining': use ScalableVectorShape2D
-nodes to make cuts in collision shapes and navigation areas.
Playing Rat's Return will give a first impression how this might work:
ScalableVectorShape2D
already ships quite some convenience methods like:
clipped_polygon_has_point(global_pos : Vector2) -> bool
andadd_clip_path(other_shape : ScalableVectorShape2D)
But I have not come around to documenting yet.
Can I change shapes in the 2D editor while running the game?
When the Update Curve At Runtime
checkbox is checked, the shape will also sync up with a scene running in debug mode.
Once you're done drawing and do not need the shape to change anymore at runtime you can turn this checkbox off again.
Attributions
Lots of thanks go out to those who helped me out getting started:
- This plugin was first inspired by Mark Hedberg's blog on rendering curves in Godot.
- The suggestion to support both
Polygon2D
and collisions was done by GeminiSquishGames, who's pointers inspired me to go further - The SVG Importer code was adapted from the script hosted on github in the pixelriot/SVG2Godot repository
- The code for making cutout shapes was adapted from the great knife tool plugin by @mrkdji
- The inspiration for using Geometry2D.offset_polyline for strokes came from @theshaggydev, who recorded this video about it.
And a big thank you goes to to @MewPurPur
The author of GodSVG for writing a great SVG Arc command implementation I could reuse here:
- Download from the GodSVG website
- Or try out the web version
- Also on itch.io
Many thanks to @HannesParth/Permotion
As an early adopter Hannes was quick to point out good quality of life improvements like snap to pixel, setting global position exactly and exporting as PNG.
Make sure to try out "Spring Ball" on Itch, a 48h game jam solo project that used ScalableVectorShape2D for all level objects, including a wrapper script to change the block that makes up the majority of the level between cube and triangle shapes:
And of course everyone who helped test and review the code thus far
- @hedberg-games
- @thiagola92
- @HannesParth
Reaching out / Contributing
If you have feedback on this project, feel free to post an issue on github, or to:
- Ask a question on reddit
- Follow my channel on youtube: @zucht2.bsky.social
- Contact me on bluesky: @zucht2.bsky.social.
- Try my free to play games on itch.io: @renevanderark.itch.io
If you'd like to improve on the code yourself, ideally use a fork and make a pull request.
This stuff makes me zero money, so you can always branch off in your own direction if you're in a hurry.
Scalable Vector Shapes 2D lets you do 3 things:
- Draw seamless vector shapes using a Path Editor inspired by the awesome Inkscape
- Animate curves of your vector shapes (useful for faces, whips, dents in cans)
- Import .svg files as seamless vector shapes in stead of as raster images
⚠️Important:
If you are updating* you may need to reload your project once for the plugin to work again, due to some renamed components.
* The safest way to update this plugin is to:
1. Save and close all your open scenes
2. Disable the plugin via `Project > Project Settings > Plugins`
3. Close your project (quit to project list)
4. Download the stable zip from github:
https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/archive/refs/tags/2.16.0.zip
5. Fully replace `res://addons/curved-lines2d` with the same directory in the zip file
6. Open your project again and enable again via `Project > Project Settings > Plugins`
7. If you see errors, just click on: `Project > Reload Current Project`
⚠️Report bugs!
Spotted a bug? Help me fix it quickly by reporting it on github:
https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/issues
Watch a 10 minute A-Z explainer on youtube:
https://www.youtube.com/watch?v=_QOnMRrlIMk
Look at some new features added since then on youtube:
https://youtu.be/pP0CYEvU2uQ?feature=shared
Inspired by Mark Hedberg's great explainer:
https://www.hedberggames.com/blog/rendering-curves-in-godot
Or ask a question on the subreddit:
https://www.reddit.com/r/ScalableVectorShape2D
Buy me a coffee:
https://buymeacoffee.com/rvanderarkp
# Changelog
## 2.16.0
### Added
- Uniform transformation buttons (move/rotate/scale all points without changing `Node2D.transform`)
- The `spin` property to represent a Rectangle / Ellipse primitive's local rotation.
### Changed
- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_ellipse_points`
- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_rect_points`
## 2.15.0
### Added
- Auto-scaling for SVG image icons on GUI controls (`Button`, `TextureButton`, `TextureRect`) using `SVGTextureHelper` (thank you to @kcfresh53)
### Changed
- Dropped class_names from GUI items in plugin itself to prevent cluttering up developers' `add node` dialog
## 2.14.3
### Added
- Bake Animation as Sprite Frames (under Advanced Editing tab) as a PNG spritesheet, or separate PNG files.
- Video explainer tab with some youtube links
- Center 2D viewport around newly created shapes...
- ...and around newly imported SVG Files
### Changed
- Bugfix: pause animation player before snapshotting sprite frame (from 2.14.0)
- Bugfix: svg importer must await first render frame before baking when not importing as `ScalableVectorShape2D`
## 2.13.4
### Changed
- Bugfix: race conditions due to unsafe pass by reference when setting `Polygon2D.polygon` in combination with `Polygon2D.polygons`
- Performance tweak: no more unnecessary invocations of `Geometry2DUtil.calculate_poly_strokes`
## 2.13.3
### Added
- New node type `AdaptableVectorShape3D` of which the shape can be changed via an assigned `ScalableVectorShape2D`
- New form `Curve Settings` added under tab `Project Settings`
### Changed
- Bugfix: svg importer now positions clip-paths correctly by using the same parent (`
- Bugfix: calculate polygons at max once per frame (major performance fix for animations)
- Adds tab `Project Settings`
- Moves `Editor Settings` to tab `Project Settings`
- Flags property `update_curve_at_runtime` on by default (changeable in `Curve Settings`)
- Flags property `resource_local_to_scene` on by default (changeable in `Curve Settings`)
## 2.13.0 - 2025-08-28
### Added
- Advanced tab in bottom panel with 3 export buttons usable on any type of selected node: PNG, Baked, 3D Scene
- Export as 3D scene (all Fills and Strokes are turned into `CSGPolygon2D` instances)
### Changed
- Bugfix: removed infinite recursion when exporting a scene root as 'Baked Scene'
## 2.12.3 - 2025-08-23
### Added
- You can now also use Polygon2D for Strokes using the `poly_stroke` property
- Collision Objects will now also get `CollisionPolygon2D`s for strokes
- Adds `signal polygons_updated(polygons: Array[PackedVector2Array], poly_strokes: Array[PackedVector2Array], self_ref : ScalableVectorShape2D)`
### Changed
- Reverts hiding of the Collision Polygon property field
- Fix: position of new shapes is now always Vector2.ZERO
- In the Stroke Inspector plugin, stroke properties are now edited on `ScalableVectorShape2D` in stead of its assigned `Line2D`:
- `line.default_color` -> `stroke_color`
- `line.width` -> `stroke_width`
- `line.begin_cap_mode` -> `begin_cap_mode`
- `line.end_cap_mode` -> `end_cap_mode`
- `line.joint_mode` -> `line_joint_mode`
- ⚠️ Please note that keyframes for all these properties are now set on `ScalableVectorShape2D` directly in stead of the assigned `Line2D`
- Fix edge cases where holes resulting from geometry operations are not handled correctly
- Rat's return example uses new signal to allow all blocks sharing the same `StaticBody2D`
## 2.11.5 - 2025-18-08
### Added
- Snap to pixel when adding points
- Snap to pixel when dragging curve edges
- Snap to pixel when dragging gradient stops
- Snap to pixel when changing rx/ry and size of primitive shapes
### Changed
- Export as 'baked' scene now supports cutouts, clips and merged shapes
- Import SVG as Node2D in stead of ScalableVectorShape2D now works with cutouts, clips and merged shapes
- Export buttons moved to inspector group `ScalableVectorShape2D > Export Options` to save screen real-estate
## 2.11.3 - 2025-14-08
### Added
- SVG Importer now supports `
Reviews
Quick Information

Scalable Vector Shapes 2D lets you do 3 things:- Draw seamless vector shapes using a Path Editor inspired by the awesome Inkscape- Animate curves of your vector shapes (useful for faces, whips, dents in cans)- Import .svg files as seamless vector shapes in stead of as raster images⚠️Important:If you are updating* you may need to reload your project once for the plugin to work again, due to some renamed components.* The safest way to update this plugin is to:1. Save and close all your open scenes2. Disable the plugin via `Project > Project Settings > Plugins`3. Close your project (quit to project list)4. Download the stable zip from github: https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/archive/refs/tags/2.16.0.zip 5. Fully replace `res://addons/curved-lines2d` with the same directory in the zip file6. Open your project again and enable again via `Project > Project Settings > Plugins`7. If you see errors, just click on: `Project > Reload Current Project`⚠️Report bugs!Spotted a bug? Help me fix it quickly by reporting it on github:https://github.com/Teaching-myself-Godot/ez-curved-lines-2d/issuesWatch a 10 minute A-Z explainer on youtube:https://www.youtube.com/watch?v=_QOnMRrlIMkLook at some new features added since then on youtube:https://youtu.be/pP0CYEvU2uQ?feature=sharedInspired by Mark Hedberg's great explainer:https://www.hedberggames.com/blog/rendering-curves-in-godotOr ask a question on the subreddit:https://www.reddit.com/r/ScalableVectorShape2DBuy me a coffee:https://buymeacoffee.com/rvanderarkp# Changelog## 2.16.0### Added- Uniform transformation buttons (move/rotate/scale all points without changing `Node2D.transform`)- The `spin` property to represent a Rectangle / Ellipse primitive's local rotation.### Changed- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_ellipse_points`- Use `Curve2D.set_block_signals` to update all points at once in `ScalableVectorShape2D.set_rect_points`## 2.15.0### Added- Auto-scaling for SVG image icons on GUI controls (`Button`, `TextureButton`, `TextureRect`) using `SVGTextureHelper` (thank you to @kcfresh53)### Changed- Dropped class_names from GUI items in plugin itself to prevent cluttering up developers' `add node` dialog## 2.14.3### Added- Bake Animation as Sprite Frames (under Advanced Editing tab) as a PNG spritesheet, or separate PNG files.- Video explainer tab with some youtube links- Center 2D viewport around newly created shapes...- ...and around newly imported SVG Files### Changed- Bugfix: pause animation player before snapshotting sprite frame (from 2.14.0)- Bugfix: svg importer must await first render frame before baking when not importing as `ScalableVectorShape2D`## 2.13.4### Changed- Bugfix: race conditions due to unsafe pass by reference when setting `Polygon2D.polygon` in combination with `Polygon2D.polygons`- Performance tweak: no more unnecessary invocations of `Geometry2DUtil.calculate_poly_strokes`## 2.13.3### Added- New node type `AdaptableVectorShape3D` of which the shape can be changed via an assigned `ScalableVectorShape2D`- New form `Curve Settings` added under tab `Project Settings`### Changed- Bugfix: svg importer now positions clip-paths correctly by using the same parent (`<g>`-node) as the clipped shape- Bugfix: calculate polygons at max once per frame (major performance fix for animations)- Adds tab `Project Settings`- Moves `Editor Settings` to tab `Project Settings`- Flags property `update_curve_at_runtime` on by default (changeable in `Curve Settings`)- Flags property `resource_local_to_scene` on by default (changeable in `Curve Settings`)## 2.13.0 - 2025-08-28### Added- Advanced tab in bottom panel with 3 export buttons usable on any type of selected node: PNG, Baked, 3D Scene- Export as 3D scene (all Fills and Strokes are turned into `CSGPolygon2D` instances)### Changed- Bugfix: removed infinite recursion when exporting a scene root as 'Baked Scene'## 2.12.3 - 2025-08-23### Added- You can now also use Polygon2D for Strokes using the `poly_stroke` property- Collision Objects will now also get `CollisionPolygon2D`s for strokes- Adds `signal polygons_updated(polygons: Array[PackedVector2Array], poly_strokes: Array[PackedVector2Array], self_ref : ScalableVectorShape2D)`### Changed- Reverts hiding of the Collision Polygon property field- Fix: position of new shapes is now always Vector2.ZERO- In the Stroke Inspector plugin, stroke properties are now edited on `ScalableVectorShape2D` in stead of its assigned `Line2D`: - `line.default_color` -> `stroke_color` - `line.width` -> `stroke_width` - `line.begin_cap_mode` -> `begin_cap_mode` - `line.end_cap_mode` -> `end_cap_mode` - `line.joint_mode` -> `line_joint_mode`- ⚠️ Please note that keyframes for all these properties are now set on `ScalableVectorShape2D` directly in stead of the assigned `Line2D`- Fix edge cases where holes resulting from geometry operations are not handled correctly- Rat's return example uses new signal to allow all blocks sharing the same `StaticBody2D`## 2.11.5 - 2025-18-08### Added- Snap to pixel when adding points- Snap to pixel when dragging curve edges- Snap to pixel when dragging gradient stops- Snap to pixel when changing rx/ry and size of primitive shapes### Changed- Export as 'baked' scene now supports cutouts, clips and merged shapes- Import SVG as Node2D in stead of ScalableVectorShape2D now works with cutouts, clips and merged shapes- Export buttons moved to inspector group `ScalableVectorShape2D > Export Options` to save screen real-estate## 2.11.3 - 2025-14-08### Added- SVG Importer now supports `<clipPath>`, `<use>` and embedded base64 encoded `<image>` (results may vary)### Changed- Use Pascal case in stead of Camel case to represent imported svg file names- Rename dock nodes in order to reference them with unique name## 2.11.2 - 2025-10-08### Added- Shortcut `Ctrl+Shift+Mousewheel` to pick cutout shape- Shortcut `Ctrl+Shift+Right click` to change clipping operation- 'Rat's return' (examples/rats_return.tscn) to illustrate shape manipulation programmatically- `Export as baked scene` button.- Flag `use_union_in_stead_of_clipping` to `ScalableVectorShape2D` which turns a cutout into a merged shape- Convenience method `clipped_polygon_has_point(global_pos : Vector2)` to detect clicks __on__ a shape without the click being in a hole- A bubbly cloud example to illustrate `use_union_in_stead_of_clipping`### Changed- Separates out the calculation of outlines and fixes most issues with it (holes within holes not working yet)- Can now cut holes in ellipses using right click in the add shapes programatically example.## 2.11.0 - 2025-06-08### Added- Preparations for svg clipPath support by adding flag `use_intersect_when_clipping` to `ScalableVectorShape2D` which turns a cutout into a clip_path by invoking `Geometry2D.intersect_polygons(...)` in stead of `Geometry2D.clip_polygons(...)`### Changed- Bugfix: svg importer can now also use gradients defined _after_ the element referring to it via `href`## 2.10.4 - 2025-06-08### Added- Mac users can now use the Cmd key in stead of Ctrl key### Changed- Bugfix: SVG importer can now handle rgb() and rgba() colors for stroke and fill- Bugfix: Style attribute of root element not is ignored anymore- SVG importer evaluates all cutouts for a shape at once- ScalableVectorShape2D caches outlines after tessellate and only reinvokes tessellate when the curve actually changes- Only recalculate curve when local transform of cutout changes (cutout has to be direct child of parent for this to trigger correctly)- Prevent global position form from being visible when plugin is enabled- Bugfix: order of undo/redo operations fixed for dragging operations## 2.10.2 - 2025-02-08### Added- You can now import an SVG file into any type of opened scene (3D, GUI, Node)- You can now create a new ScalableVectorShape2D in any type of opened scene### Changed- Using uniqe names in stead of `find_node` to refer to tool controls- SVG importer only creates cutout when initial point of follow-up path is _inside_ first shape- Bugfix: svg transform attribute now supports multiple transform commands- Bugfix: can now perform svg transform translate(...) with one parameter as well as two- Bugfix: resets the cursor position of follow-up paths correcty now (after the z/Z command)- Bugfix: SVG importer sets rx/ry values compliantly now## 2.9.2 - 2025-31-07- Added pinball starter example in examples dir## 2.9.1 - 2025-27-07### Added- Use Ctrl+Shift+Left click to create a cutout shape for the selected shape- One shape can have multiple cutout shapes assigned (via the `clip_paths` property)- Cutouts can be holes, made possible by multiple polygons- Cutouts are `ScalableVectorShape2D` nodes themselves with all the same capabilities- A `NavigationRegion2D` can now be assigned via the `navigation_region` property- The SVG importer now also supports cutout paths within the `d="..."` attribute (results may vary)## 2.8.2 - 2025-21-07### Added- The `collision_object` property is meant to replace the `collision_polygon` property- This will hold an assignment to a descendant of `CollisionObject2D` (`Area2D`, `StaticBody2D`, etcetera)- This managed `CollisionObject2D` will get directly generated `Polygon2D` children from the plugin### Changed- The `collision_polygon` property is now marked as deprecated (but will function the same for backward compatibility)- Bugfix: fixed parsing bug for quadratic bézier curves### Removed- Removed the assignment inspector form field for the `collision_polygon` property once it has been unassigned## 2.7.1 - 2025-16-07### Added- Add direct arc support for ScalableVectorShape2D: moving arcs around is now much easier by replacing many points by just the 2 (start and end)- The arcs can be dynamically manipulated via metadata fields (radius, rotation, large arc, sweep -> see: [svg specification](https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands))- The arcs can also be animated using the `Curve Settings > Batch insert` button for key frames### Changed- Bugfix: fixed index out of bounds for scale-transform in svg importer.- Removed `Rat` class_name from the rat example to prevent name conflicts.## 2.6.6 - 2025-11-07## Changed- Bugfix: SVG importer can now handle negative numbers without leading whitespace- Bugfix: SVG importer now handles multiple shapes in one svg path element## 2.6.5 - 2025-10-07### Added- SVG importer now supports the arc command (fixed at 4 degree angles for now)## 2.6.4 - 2025-01-07### Changed- ScalableVectorShape2D nodes can only be selected when mousedown and mouseup event registered on the same node ('click'-event)- ScalableVectorShape2D nodes can now only be selected when they are visible- ScalableVectorShape2D nodes can not be selected anymore when they are locked using the lock-icon- ScalableVectorShape2D nodes can not be selected anymore when they are part of a different scene## 2.6.3 - 2025-06-15### Added- Change line-capping of strokes via inspector- Change line-joining of strokes via inspector- Pick default line-cap and line-join modes for creating new strokes- Maps line-join modes and line-cap modes from SVG to Godot using the importer- Pixel snap mode checkbox, disabled by default- Show point positions under editor hints- Form to set exact global position for curve point and handles (in path mode)- Export as PNG button in inspector form of ScalableVectorShape2D### Changed- "Show point numbers" renamed to "Show point details", also toggles position info on/off- Bugfix: build failures due to internal tool class referenced at runtime## 2.5.2 - 2025-06-08### Added- Makes Rectangles editable using one size handle and two rounded corner handles- Makes Ellipses editable using one size handle- Adds create buttons for Rectangle as Rectangle and Ellipse as Ellipse- ..next to exists create buttons for them as Path- Adds a "convert to path" button in the inspector when `shape_type` is a rectangle or ellipse### Changed- Enhancement: newly created Rectangle has its origin at its natural center, in stead of its top/left corner- Bugfix: gradient stop color order stays in tact after undo remove- Bugfix: Bottom Panel is more visible after fresh install- Bugfix: preloading replaced by loading to fix busy resource issues in inspector plugin code- Bugfix: previewed shape has scaled stroke### Removed- Custom collapse / expand titles from inspector plugin forms in favour of `@export_group` annotations on `ScalableVectorShape2D`## 2.4.3 - 2025-06-07### Changed- Fixed a preloading + busy device bug in inspector plugin load script## 2.4.2 - 2025-06-05### Added- Batch insert key frame button for entire curve- Batch insert key frame button for entire gradient- Key frame button for stroke width- Key frame button for fill stroke color- Key frame button for fill color### Changed- Fixes ordering bug of gradient stop color buttons- Reconnects import svg button to file dialog in svg importer panel## 2.3.2 - 2025-05-31### Added- Adds gradient fill toggle to the inspector form- Adds gradient stop color buttons to the inspector form- Adds gradient start- and end handle to 2D editor- Adds stop color handles to 2D editor- Implements paint-order correctly in SVG importer- Better tooltips for SVG importer- Warning message for unsupported clipping (using 'm'- / 'M'-operator) in SVG importer### Changed- Bugfix: resizes the gradient texture when the bounding box changes- Regression fix: all the SVG importer settings in the SVG importer form work again## 2.2.1 - 2025-05-28### Added- Adds easier to use forms for Stroke, Fill and Collision shape to the `ScalableVectorShape2D` inspector- Adds project settings for defaults like stroke width, stroke and fill colors, and paint order- Separates the point numbers from the hint labels- Saves project settings for enabling and disabling hints and viewport editing- Shows a preview of the shape which is about to be added via the bottom panel- Explanatory tooltips for all the fields and options that are not self-explanatory enough## 2.1.3 - 2025-05-24### Added- Undo/Redo for strokes (`Line2D`) fills (`Polygon2D`) and collisions (`CollisionPolygon2D`) added with the `Generate` button in the inspector- After Undo of creating a new shape from the bottom panel, its parent node is automatically selected again- Resize a shape without using the `scale` property using `Shift+mousewheel`, for more pixel perfect alignment### Changed- Fix: after adding point on line with double click, the correct point is removed again with undo- Fix: when a curve is closed, it stroke (the `Line2D` assigned to the `line`-property) is also closed and vice-versa- Fix: closing a shape now works by simply adding a segment between the last and first point## 2.1.0 - 2025-05-21### Added- Use `Ctrl+click` to add points to a shape faster- Undo/Redo support for shapes from the bottom panel### Changed- Shapes from the bottom panel are added as child of the selected node- When no node is selected, shapes from the bottom panel are added in the center of the viewport- Batched Undo/Redo for all mouse drag operations- Tooltip and ability to copy link with right click on `LinkButton` to external content## 2.0.0 - 2025-05-19### Added- Custom node `ScalableVectorShape2D` introduced, enabling editing of its `Curve2D` using the mouse similar to the popular open source vector drawing program [Inkscape](https://inkscape.org/)- Add a circle, ellipse or rectangle from the bottom panel directly- Ability to Undo/Redo many drawing operations- A more comprehensive manual in the [README](./README.md)### Changed- The custom node `DrawablePath2D` was deprecated in favor of `ScalableVectorShape2D`## 1.3.0 - 2025-05-10_Last stable release of EZ Curved Lines 2D_This shipped 2 things:- An SVG file importer, which transforms shapes into native Godot nodes- The custom node `DrawablePath2D`, which extends from Godot's `Path2D` to use its built-in `Curve2D` editor