Commit Graph

662 Commits

Author SHA1 Message Date
Keavon Chambers 4d5dce976e
Replace the control bar's stroke weight with a full stroke properties popover (#4145)
* Replace the control bar's stroke weight with a full stroke properties popover

* Code review
2026-05-13 03:58:12 -07:00
Keavon Chambers 629a1f4b4c
Redesign how the control bar handles fill and stroke colors (#4137)
* Revamp how the control bar handles fill and stroke colors

* Fix bugs

* Code review
2026-05-11 18:13:02 -07:00
Keavon Chambers a28b9437aa
Rename the "Table" type to "List" everywhere (#4133)
* Rename the "Table" type to "List" everywhere

* Fix a few missed ones

* Re-save demo artwork
2026-05-09 01:33:39 -07:00
Keavon Chambers cb21e5960b
Remove serialization from Table<T> and make TaggedValue only store tooling/widget node inputs (#4129)
* Add TaggedValue::TypeDefault to avoid baking placeholder Tables into saved documents

* Add TaggedValue::TypeDefault to avoid baking placeholder Tables into saved documents

* Migrate empty Vector/Raster/Graphic/Artboard placeholder values to TypeDefault on load

Documents written before the TypeDefault mechanism existed have empty Table<Vector>/<Raster>/<Graphic>/<Artboard> values baked into every unwired exposed input. Walk each migrated node's inputs and rewrite any such placeholder NodeInput::Value into the equivalent NodeInput::type_default, so re-saved documents shed the placeholder payloads. Marked with a TODO for eventual removal once enough documents have been re-saved.

* Re-save demo artwork

* Remove Graphic and Artboard placeholder containers from TaggedValue

* Remove Raster placeholder TaggedValue variant

* Simplify document migration

* Remove Vector placeholder TaggedValue variant

* Remove NodeIdTable from the TaggedValue

* Remove StringTable from the TaggedValue

* Remove F64Table in place of F64Array in TaggedValue

* Replace TaggedValue::Color(Table<Color>) with ::Color(Option<Color>)

* Replace TaggedValue::GradientTable(Table<GradientStops>) with ::Gradient(GradientStops)

* Replace TaggedValue::BrushStrokeTable(Table<BrushStroke>) with ::BrushStrokes(Vec<BrushStroke>)

* Make TaggedValue::DocumentNode runtime-only with TypeDefault placeholder

* Make TaggedValue::ContextFeatures runtime-only

* Remove Serialize/Deserialize from Table<T>

* Add a widget for TaggedValue::BrushStrokes to visualize strokes and samples

* Define a reusable list of TaggedValue::TypeDefault types for its generated methods

* Re-save demo artwork
2026-05-08 16:11:25 -07:00
Keavon Chambers 525e49f7e9
Make the Shape tool's modes' parameter controls sync with the selected shape layer (#4121)
* Make the Shape tool's modes' parameter controls sync with the selected shape layer

* Fix populating the Shape tool mode selection list
2026-05-07 02:42:39 -07:00
Keavon Chambers 1596469e92
Make the drawing tools' Weight control sync with the selected layer (#4120) 2026-05-07 02:12:38 -07:00
Keavon Chambers 9512f7df41
Make the Gradient tool default to the primary/secondary working colors as its initial gradient (#4119)
* Make the Gradient tool default to the primary/secondary working colors as its initial gradient

* Fix drawing direction
2026-05-07 01:41:01 -07:00
Keavon Chambers 24c857ddc7
Make the Text tool control bar font family, style, and size sync with the selected layer (#4118)
* Fix contenteditable preview alignment

* Make the Text tool control bar font family, style, and size sync with the selected layer

* Tidying up
2026-05-06 20:50:41 -07:00
Keavon Chambers 2ae35a67e7 Add icons for text alignment/justification 2026-05-06 19:26:26 -07:00
Jatin Bharti c0a8241f50
Add text last-line alignment modes for "Justify Center", "Justify Right", and "Justify All" (#4024)
* feat: Add justify proper alignments(right/left/centre/all)

* chore: fmt

* chore: refactor

* Cleanup

* Fix crash when changing selected layer's alignment from the Text tool control bar

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-05-06 19:16:19 -07:00
Keavon Chambers d106bedecd
Fix Pen tool regression that broke dragging a sharp tangent out of the last-placed anchor (#4115) 2026-05-06 03:16:24 -07:00
Keavon Chambers ecf94258fa
Fix tool overlays and snap targets to use upstream Path node geometry, not downstream final geometry (#4114)
* Fix tool overlays and snap targets to use upstream Path node geometry not downstream final geometry

* Snap to upstream Path free points, dedupe the lookup via a helper
2026-05-06 03:00:38 -07:00
Keavon Chambers 21e5e06b0b
Clean up document message wrappers around proto nodes so they're now used directly (#4101)
* Rename the 'Identity' node to 'Passthrough' internally

* Rename the 'Memoize'  node to 'Cache' internally

* Let skip_impl proto nodes auto-generate as document node definitions

* Remove the wrapper 'Passthrough' node from document_node_definitions.rs

* Remove the wrapper 'Cache' node from document_node_definitions.rs

* Remove the wrapper 'Monitor' node from document_node_definitions.rs

* Remove the wrapper 'Noise Pattern' node from document_node_definitions.rs

* Remove the wrapper 'Brush' node from document_node_definitions.rs

* Remove the wrapper 'Transform' node from document_node_definitions.rs

* Code review improvements

* Rename Cache node back to Memoize

* More code review
2026-05-03 19:26:36 -07:00
Keavon Chambers ebdb835890
Properly track the Text node's text frame via the attribute system to fix misalignment (#4097)
* Compensate for upstream row-0 transform absorption in viewport-space 'TransformSet'

* Add 'editor:text_frame' row attribute so the Text tool's drag cage tracks multi-row text

* "Separate Glyph Elements" -> "Separate Glyphs"

* Improve artboard migration robustness from older documents

* Code review

* Make the tools visualize the text frame based on attribute not upstream node
2026-05-02 21:04:30 -07:00
Keavon Chambers 325e9aff06
Add custom click targets to make Text node output easier to select (#4095)
* Stop pushing duplicate layer entries when re-clicking an already-selected layer

* Make Text node generate per-glyph bounding box click targets

* Show source-geometry outlines and aggregate all rows for layer click targets

* Strip 'editor:click_target' override on Path node so direct edits restore precise hit testing

* Fix inverting a zero-determinate transform
2026-05-02 18:12:42 -07:00
Keavon Chambers a0d5f418d9
Replace Table<Table<Graphic>> with Table<Artboard> where Artboard is a type boundary newtype (#4093)
Replace Table<Table<Graphic>> with Table<Artboard> with Artboard as a type boundary newtype
2026-05-01 21:57:50 -07:00
Keavon Chambers 83d03ad67d Fix panel docking bugs and polish its behavior (#4087)
* Fix panel docking bugs and polish its behavior

* Fix bug
2026-05-01 17:02:10 +00:00
Keavon Chambers 86134c26b4
Remove the 'Blending' node, moving clip into a new 'Clipping Mask' node and fill into the 'Opacity' node (#4085)
* Separate 'Clip' into its own node out from the removed 'Blending' node

* Code review

* Rename to Clipping Mask

* Update Opacity node in demo art that use it

* Use DIsplay not Debug for printing blend modes
2026-04-30 20:04:04 -07:00
Keavon Chambers 4b2430290c
New nodes: 'Gradient Type' and 'Spread Method', and add Gradient tool support for controlling these nodes (#4084)
* Use 'Transform', 'Gradient Type', and 'Spread Method' nodes for table gradients

* Add gradient widget to the tool's control bar and update where the two swap buttons go

* Fix gradient rendering

* Format

* Code review
2026-04-29 19:27:44 -07:00
YohYamasaki e686ee9f42
Add Table<GradientStops> gradient rendering (#3989)
* Add Table<GradientStops> gradient rendering

* Add SVG and Vello renderers for Table<GradientStops>

* Add thumbnail rendering for Table<GradientStops>

* Use row transform to map (0,0), (1,0) unit line to document space

* Set 100px width for the initially created gradient

* Add support of table gradients for the gradient tool

* Fix after review

* Thumbnail rendering of artboard with infinite gradient layer

* Hide radial gradient's reverse direction button for gradient table

* Remove unused imports

* Format

* Fix conflict with spread method

* Code review

* Fix thumbnails

* Connect up gradient_type and spread_method to attributes

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-04-29 05:45:50 -07:00
Keavon Chambers ba63c26c62 Replace the Artboard struct with a Table<Table<Graphic>> shape (#4077)
* Replace the Artboard struct with a Table<Table<Graphic>> shape

* Remove the never-functional, seemingly unneeded migrate_type_descriptor_names due to typo

* Allow negative artboard sizes
2026-04-28 22:58:33 -07:00
Keavon Chambers 5774ec215d Replace deprecated row/cell/instance terminology with "item" and "value" terms (#4075) 2026-04-28 19:12:59 -07:00
Keavon Chambers b396d17211 Migrate remaining node graph data types from Vec to Table (#4067)
* Move Vec<String> to Table<String>

* Remove old VecDVec2

* Move Vec<u8> to Table<u8>

* Move Vec<f64> to Table<f64>

* Move [f64; 4] to Table<f64>

* Move Vec<NodeId> to Table<NodeId>

* Tidy up the TaggedValue variants

* Move Vec<BrushStroke> to Table<BrushStroke>

* Add missing type implementations

* Fix tests

---------
2026-04-28 13:44:25 -07:00
Keavon Chambers 76938eb69a Implement dynamic table attributes to generalize the graphic-specific Table type (#4050)
* Feature-gate serde derives behind cfg_attr in all runtime node graph type crates

* Refactor Table to move its hard-coded fields into an attributes field

* Encapsulate TableRow/TableRowRef/TableRowMut attribute fields behind accessor methods

* Remove TaggedValue::GraphicUnused

* Refactor Table<T> to use dynamic attributes instead fixed names

* Fix code review soundness concerns

* Add todo work

* Replace row-oriented Table<T> API with column-oriented access

* Fix attribute propagation bugs

---------
2026-04-28 03:25:16 -07:00
Dennis Kobert 3d84e63ef9
Migrate usage of the Hash trait for cache invalidation to the dedicated CacheHash trait (#4051)
* WIP start migrating usages of hash for cache invalidadion to dedicated trait

* Finish migrating usages

* Code review

* Add comments clearifying the reasoning for using random ids in the VectorModification cach hash impl

* Fix some remaining hash violations

* Finish migration and fix compilation

* Fix import ordering

* Cleanup

* Fix code review stuff

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-04-27 05:18:47 +00:00
Keavon Chambers d3f36a95cf
Rename 'Image Value' node to 'Image' and have its input value be an image not a raster table (#4037)
* Rename 'Image Value' node to 'Image' and have its input value be Image<Color> not Table<Raster<CPU>>

* Add a Properties panel widget labeling "width x height" for images in the Image node

* Add Image<Color> node registry entry for MonitorNode

* Code review
2026-04-22 16:00:03 -07:00
Timon 6c5e3c97f8
Refactor persistence to combine document handling and workspace layout (#4031)
* Unify editor state persistence

* Review

* Fix

* Remove redundant DocumentDetails

* LoadDocumentContent indirection
2026-04-19 09:31:21 +00:00
YohYamasaki 79d778a535
Add support for setting the spread method for gradient fills (#3953)
* Add spread method support for gradients

* Add GradientSpreadMethod enum (Pad, Repeat, Reflect) to vector-types

* Add radio buttons to gradient tool and fill properties panel

* Convert spread method when importing SVGs via usvg

* Sync backup gradient input when changing spread method

* Table<GradientStops> rendering is not yet updated for spread method

* Sync gradient tool options with layer's gradient

* Sync gradient_type and spread_method from the selected
  layer's existing gradient to the tool options bar when
  switching to the gradient tool

* Refactor has_gradient_on_selected_layers
  to reuse a new get_gradient_on_selected_layer helper

* Swap Reflect and Repeat order in UI radio buttons

* Fix alignment of the radio buttons in right panel

* Fix the position of the radio buttons in the tool

* Rename SpreadMethod to SetSpreadMethod

* Move default spread method omission logic
2026-04-14 08:09:57 +00:00
Keavon Chambers da45ab2f87
Add a checkered background to transparent artboards and the infinite canvas (#4022)
* Add checkered transparency rendering to infinite canvas and artboards

* Enable artboard clipping by default

* Make new infinite canvas documents begin with a white background layer

* Remove the export dialog's transparency option now that it's redundant

* Make exporting transparent JPGs use white not black

* Code review
2026-04-10 03:21:21 -07:00
Keavon Chambers 4360359d60
Finalize and unify the design of the 'Morph' and 'Blend' nodes (#3974)
* Fix Morph node transform interpolation and preservation in the table

* Fix click target positions for Morph's nested layers by pre-compensating upstream_data transforms

* Redesign Morph node (v3) with control path input and uniformly spaced progression, and fix Stroke::lerp interpolation weights

* Add migration from Morph node v2 to v3

* Redesign the 'Blend Shapes' node behavior and subgraph definition

* Add the Layer > Blend menu entry to easily set up a blend

* Optimize the Morph node

* Refactor the Morph node to remove the roundtrip through BezPath

* Fine-tune Morph node Bezier order promotion and handle interpolation

* Add the Layer > Morph menu bar entry

* Fix NaN and guard against other potential NaN bugs breaking the editor

* Add InterpolationDistribution parameter to Morph with weighted progression, swap parameter orders, and rename shear to skew

* Add the Reverse parameter to the Morph node

* Update the order of the inputs to Blend Shapes for consistency with Morph

* Make Layer > Morph create the Morph Path control layer

* Fix migrations

* Move 10 to a constant

* Avoid division by 0 in the Blend Shapes node internals

* Rename nodes 'Blend' -> 'Mix' and 'Blend Shapes' to 'Blend'

* Fix a crash encountered while testing

* Final code review

* Make domain push dupe checks debug-only and use push_unchecked in the Morph node

* Pre-allocate for pushes to the vector domains

* Add fast path at t=0

* Inline reserve()

* Set up the control path layer above not below, and starting collapsed

* Review fixes

---------

Co-authored-by: Timon <me@timon.zip>
2026-04-03 20:45:58 -07:00
Keavon Chambers 87bd3d41df Make Alt+click on a handle in the Path tool split it from its colinear pair 2026-04-01 23:04:56 -07:00
Keavon Chambers 1543d974ac
Fix 'Jitter Points' and 'Sample Polylines' working incorrectly with X or Y scale of 0 content (#3984)
* Fix NaN points produced by Sample Polylines on 0-scaled input

* Fix Jitter Points inverse transform for zero-scale axes and stop resetting stroke transform

* Remove a couple confusing Debug nodes

* Fix edge case

* Update demo art

* Fix order change in Jitter Points causing different results from earlier

* Fix bug in bisect tool

* Break out functionality into helper functions
2026-04-01 22:51:48 -07:00
Keavon Chambers 6388a32ac5
Fix an assortment of small bugs (#3968)
* Fix an assertion failure bug when scaling a line in the transform cage

* Fix missing defaults on node gradient inputs

* Fix Blend Shapes path input wire not updating to show in the UI after Layer > Blend

* Fix assertion failure due to browser non-monotonic timestamp

* Fix SVG renderer drawing 1px strokes as half-width when using stroke alignment

* Fix incorrect appearance of the ColorInput widget when set to "none" and "disabled"

* Fix lerp function in Fill enum to handle None cases correctly

* Fix stroke alignment bug
2026-03-28 17:12:13 -07:00
Keavon Chambers 11b7af61ef
Fix image and SVG import transform bugs (#3942)
* Fix half-pixel offset on imported images

* Break out reused function

* Fix SVG/image open flow placing content with unnecessary Transform nodes

* Fix redundant Transform nodes when opening SVG/image files as documents

* Offset the parent to its destination position not the child objects

* Fix SVG/image File > Open artboard dimensions, origin, and clipping

* Fix the SVG to drag in at the mouse position relative to its visible center

* Fix importing images into offset artboards so they don't get offset as well

* Code review
2026-03-23 16:26:10 -07:00
Keavon Chambers 81d0b8b8d4
Fix the Eyedropper tool on web with Vello and on desktop with SVG (#3886) 2026-03-11 03:26:02 -07:00
Dennis Kobert 90533e656f
Remove the path-bool library (#3882) 2026-03-11 08:55:03 +01:00
Kulcode 3a7a5f5953
Fix incorrect transform space for Select tool origin pivot visualization ball (#3850)
Fix
2026-03-10 11:19:44 +00:00
Keavon Chambers 2910e50b2f
Improve Shape tool arrow mode interactive drawing with angle modifier keys and endpoint gizmos (#3874)
* Make the order of Shape tool shape types consistent

* Add Arrow shape modifier keys and snapping support

* Add endpoint dragging to arrows

* Show the default cursor when hovering line/arrow endpoints

* Reduce duplicated function

* Fix incorrect coordinate spaces

* Improve endpoint dragging clarity
2026-03-10 03:41:35 -07:00
Ayush Amawate e7a2800665
Fix Shape tool type dropdown not persisting selection and not excluding Line/Rectangle/Ellipse (#3731)
* fix Shape tool dropdown resetting to Polygon when switching tools

* add sync for rectangle/ellipse and line

* fix build issues
2026-03-10 08:25:44 +00:00
Keavon Chambers 9f9dd71e91
Fix vector drawing tool transform space handling (#3872)
* Fix vector drawing tool transform space handling

* Review fixes

* Fix test
2026-03-10 00:58:51 -07:00
Ayush Amawate 20501cac96
Fix Shape tool layer creation to not make the Transform node to appear after the Stroke node (#3854)
Fix shape stroke thickness

remove redundant call

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-03-10 01:41:43 +00:00
Keavon Chambers 52d2b38a82 Refactor the TypeScript data flow for full type safety and auto-generation of Rust types (#3865)
* Migrate Specta to Tsify to auto-generate messages.ts, working except colors and widgets

* Adopt the generated FillColor/Color/GradientStops

* Fix widget typing

* Separate WidgetGroup enum variants into wrapper structs

* Small rename

* Simplify widgets further

* Clean up message type references

* Switch type imports to the auto-generated file

* Remove lowercase serde rename

* Fix FillChoice deserialization

* Fix small regression from #3837

* Improve type safety

* Make WidgetSpan type-safe

* More cleanup and type safety

* More type safety

* More type safety

* Get the rest to type-check without errors; improve widget builder macro to have optional icons; improve Svelte 5 configs

* Cargo fmt

* Fix imports

* Update outdated readme info

* Fix lint command rename references

* Fix typos

* One more typos fix

* Remove unnecessary dep: prefix from the edited Cargo.toml files

* Remove excess parts from Cargo.toml

* Fix compiling on desktop

* Revert "Remove excess parts from Cargo.toml"

This reverts commit 6b711117b3a5d5d8a3ee20f36a43bc74930b7c82.

* Update dev docs with simpler, more accurate instructions
2026-03-09 16:35:04 -07:00
Keavon Chambers 8a1dfb9d8f
Refactor messages.ts by removing class-transformer and JS classes (#3858)
* Fix gamma correction with HTML-based editable Text tool text

* Migrate simple, undecorated classes to types

* Remove TupleToVec2 transformation

* Remove @Transform from tooltips

* Cleanup: replace value.toString() with String(value) everywhere

* Convert documentId from string to bigint

* Migrate the rest of the easy @Transform/@Type decorations

* Migrate FillChoice

* Migrate WidgetDiffUpdate

* Migrate WidgetInstance

* Migrate away from classes that extend WidgetProps

* Remove class-transformer and all classes in messages.ts

* Migrate UI layout passing

* Remove dead code

* Remove unnecessary export and readonly prefixes

* Remove HSVA type

* Break out Color, Gradient, and FillChoice functions into a utility-functions file

* Move widget helper functions from messages.ts into a new utility-functions file; restructure type imports

* Reduce internal type defs

* Rename JsMessage to FrontendMessage

* Code review fixes

* Fix other usages

* Tidying up
2026-03-05 01:43:21 -08:00
Keavon Chambers a8b5203d6c
Clean up code for drawing overlays to accept sRGB hex codes instead of Color structs (#3839)
* Clean up code for drawing overlays to accept sRGB hex codes instead of Color structs

* Consolidate hex code parsing functions
2026-02-27 14:08:58 -08:00
Keavon Chambers 9ecbfb7110
New nodes: RGBA to Color, HSVA to Color, Hex to Color, and Read Gradient (#3838)
* New nodes: RGBA to Color, HSVA to Color, Hex to Color, and Read Gradient

* Simplify
2026-02-26 18:22:04 -08:00
Keavon Chambers e62771845f
Add an in-viewport color picker to the Gradient tool when double-clicking a color stop (#3834)
* Hide batched blocked debug print messages

* Implement the color picker on double-clicking stops

* Code review
2026-02-25 21:03:12 -08:00
Keavon Chambers 8117ddcdb3
Add Gradient tool control bar buttons, Reverse Stops and Reverse Direction (#3830)
* Add Gradient tool control bar buttons, Reverse Stops and Reverse Direction

* Consolidate reused gradient line updating code
2026-02-25 00:48:21 -08:00
Keavon Chambers b4679b0675
Improve Gradient tool dragging behavior and make hints reactive to current interaction state (#3828)
* Improve Gradient tool dragging behavior and make hints reactive to current interaction state

* Reduce code duplication for drawing stops

* Fix coordinate system issue when PTZ'ing document during drag or autopan
2026-02-24 22:17:29 -08:00
Keavon Chambers 4a6cdffd84
Add draggable diamond midpoint gizmos to the Gradient tool (#3826) 2026-02-24 20:25:15 -08:00
Kulcode 3b91d02fff
Add snapping to endpoints and stops in the Gradient tool (#3732)
* snapping

* Cleanup

* fix

* Fix snapping failing sometimes on newly drawn gradient lines

* Code cleanup

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-02-24 04:48:28 +00:00