website/content/blog/2025-03-31-graphite-progress-report-q4-2024.md
+++ title = "Graphite progress report (Q4 2024)" date = 2025-03-31 [extra] banner = "https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024.avif" banner_png = "https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024.png" author = "Keavon Chambers & Hypercube" summary = "Graphite's Q4 2024 update introduces quality of life features across drawing tools and procedural editing." css = ["/component/demo-artwork.css"] reddit = "https://www.reddit.com/r/graphite/comments/1jpjqcs/blog_post_graphite_progress_report_q4_2024/" twitter = "https://x.com/GraphiteEditor/status/1907350199414206604" bluesky = "https://bsky.app/profile/graphiteeditor.bsky.social/post/3llsxykppjs2c" +++
Graphite, a new open source 2D procedural graphics editor, has wrapped up 2024 with a fourth quarter (October-December) focused on introducing quality of life features for both Graphite's interactive tools-driven and procedural editing workflows.
<!-- more -->All Q4 2024 commits may be viewed in this list and all noteworthy changes are detailed below.
This is the fourth in our 2024 series of quarterly progress reports. If you missed the previous post, be sure to check it out as well. If you'd like to help speed up future progress, please consider getting involved with code, QA/bug testing, or art/marketing projects. Donations are also valued, as are stars on GitHub. Follow along and partake in our Discord community, too.
At the time of publication, there is one week left to apply for a summer 2025 internship with us through Google Summer of Code. Learn more here and apply before April 8 at 18:00 UTC.
To showcase the newly introduced feature of converting selected nodes into conveniently reusable subgraphs, the new Parametric Dunescape artwork is presented below. Every dune layer is generated just by its custom parameters for color, height, and random seed.
<div class="demo-artwork"> <a href="https://editor.graphite.art/#demo/parametric-dunescape"></a>
<p>
<span>
<em>Parametric Dunescape</em>
</span>
<span>
<a href="https://editor.graphite.art/#demo/parametric-dunescape">Open this artwork</a> to
explore it yourself. </span> </p>
</div>Node graph support for making a custom node by merging the selected nodes into a subgraph with the node context menu's "Merge Selected Nodes" option, or the shortcut <kbd>Ctrl</kbd><kbd>M</kbd> (macOS: <kbd>⌘</kbd><kbd>M</kbd>) <small>(#2097)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/merge-selected-nodes.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/merge-selected-nodes.mp4" type="video/mp4" /> </video> </div>Text controls for line height, character spacing, and wrappable box areas that can be dragged with the Text tool <small>(#2016, #2118)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/text-area-controls.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/text-area-controls.mp4" type="video/mp4" /> </video> </div>Pinnable node sections in the Properties panel <small>(commit e6d8c47)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/pinnable-node-sections.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/pinnable-node-sections.mp4" type="video/mp4" /> </video> </div>New demo artwork, Changing Seasons, featured in the previous progress report <small>(commit fa6b5f2)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/changing-seasons-demo.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/changing-seasons-demo.mp4" type="video/mp4" /> </video> </div>Offset Path node that expands or contracts a vector shape <small>(#2030)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/offset-path-node.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/offset-path-node.mp4" type="video/mp4" /> </video> </div>Flatten Vector Elements node that turns multiple layers of vector paths into a single combined path; and changes to the Copy to Points, Repeat, and Circular Repeat nodes so they output group data instead of a single vector path, allowing each separate layer to be modified by nodes which operate on groups (like Assign Colors), or flattened with Flatten Vector Elements to have the prior behavior <small>(#2011, #2045)</small>
Support for Fill and Stroke nodes with groups, applying to each vector layer within <small>(#2046)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/fill-and-stroke-nodes-on-groups.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/fill-and-stroke-nodes-on-groups.mp4" type="video/mp4" /> </video> </div>Switch node that routes one of two data connections based on a true or false value <small>(#2064)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/switch-node.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/switch-node.mp4" type="video/mp4" /> </video> </div>Bevel node that flattens the corners of vector shapes <small>(#2067, #2096)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/bevel-node.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/bevel-node.mp4" type="video/mp4" /> </video> </div>Jitter Points node that randomly offsets each point in a vector path <small>(commit 7d86bf4)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/jitter-points-node.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/jitter-points-node.mp4" type="video/mp4" /> </video> </div>Node insertion button, and layer renaming, directly from the Properties panel <small>(#2072, #2081)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/node-insertion-button-in-properties-panel.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/node-insertion-button-in-properties-panel.mp4" type="video/mp4" /> </video> </div>Path tool feature where pressing <kbd>Space</kbd> while dragging a handle makes the anchor be dragged as well <small>(#2065)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-space-to-drag-anchor.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-space-to-drag-anchor.mp4" type="video/mp4" /> </video> </div>Path tool feature where pressing <kbd>Tab</kbd> while dragging a handle makes it swap to the opposite handle <small>(#2058)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-tab-to-swap-handle.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-tab-to-swap-handle.mp4" type="video/mp4" /> </video> </div>Pen tool feature allowing the connection of layers by their endpoints so they both get merged into a single layer <small>(#2076)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/pen-tool-combining-layers.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/pen-tool-combining-layers.mp4" type="video/mp4" /> </video> </div>Clamp node that limits an input number between a minimum and maximum range <small>(#2087)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/clamp-node.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/clamp-node.mp4" type="video/mp4" /> </video> </div>To U32 and To U64 nodes that convert numbers to a positive integer type required by a few nodes, as a workaround for automatic type conversion not being fully supported yet <small>(#2087)</small>
Dot Product node that calculates the mathematical dot product between two numerical vectors <small>(#2126)</small>
Math node that calculates a custom math expression with variables "A" and "B" <small>(#2121)</small>
Degrees/radians option in the trig-related math nodes and "Always Positive" option in the Modulo node for more convenient usage of the math nodes <small>(commit d649052)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/modulo-and-trig-node-additions.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/modulo-and-trig-node-additions.mp4" type="video/mp4" /> </video> </div>Node graph control bar revamp <small>(#2093)</small>
Freehand tool feature for drawing new subpaths on an existing vector layer by holding <kbd>Shift</kbd> <small>(commit ed119ad)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/freehand-tool-draw-appended-to-layer.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/freehand-tool-draw-appended-to-layer.mp4" type="video/mp4" /> </video> </div>Proper automatic placement of layers into the artboard they're drawn inside of <small>(#2110)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-placement-into-artboard-drawn-on.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-placement-into-artboard-drawn-on.mp4" type="video/mp4" /> </video> </div>Menu bar additions of Layer > New, Layer > Group Selected, and Layer > Delete Selected <small>(commit feba874)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-menu-bar-additions.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-menu-bar-additions.mp4" type="video/mp4" /> </video> </div>Select tool box selection feature for subtracting the targetted layers from the active selection with a modifier key as shown in the contextual input hints at the bottom of the editor <small>(#2162)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/box-selection-subtraction.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/box-selection-subtraction.mp4" type="video/mp4" /> </video> </div>Path tool feature for snapping to 15° increments and locking the angles of dragged handles when <kbd>Shift</kbd> and <kbd>Ctrl</kbd> modifier keys are pressed <small>(#2160)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-angle-locking-and-15deg-increments.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/path-tool-angle-locking-and-15deg-increments.mp4" type="video/mp4" /> </video> </div>Support for multiple top output wires extending from the same layer stack <small>(#2049)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-stack-multi-top-outputs.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-stack-multi-top-outputs.mp4" type="video/mp4" /> </video> </div>Style improvements to the Layers panel UI to clarify which layers contain selected children, even if hidden within a collapsed layer which previously obscured where selected layers were within the hierarchy <small>(commit 1264ea8)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-panel-show-selected-within-collapsed.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/layer-panel-show-selected-within-collapsed.mp4" type="video/mp4" /> </video> </div>Revamped quick measurement overlays now supporting every layer arrangement scenario <small>(#2147, #2155)</small>
<div class="video-background"> <video autoplay loop muted playsinline disablepictureinpicture disableremoteplayback> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/quick-measurement-improvements.webm" type="video/webm" /> <source src="https://static.graphite.art/content/blog/2025-03-31-graphite-progress-report-q4-2024/quick-measurement-improvements.mp4" type="video/mp4" /> </video> </div>