177 Commits

Author SHA1 Message Date
Igor Zinken
3f94cc548b Address issues when filling or stroking out-of-visual-bounds Selections (#99)
When zooming in and panning the Viewport while a Selection is active, if a bucket fill or stroke operation is used, only the visible area of the Selection is filled.

This should be updated to fill the full area, even the out of visual bounds area.

This changeset also fixes an issue where stroke width would be applied differently at different zoom levels.
2026-05-01 21:33:03 +02:00
Igor Zinken
6584c86633 Add feather and threshold control to smart fill tool 2026-04-26 11:46:29 +02:00
Igor Zinken
a4a86acb64 Fix issue where drag-to-cut-selection action would move the original Layer on long async operations 2026-04-25 10:45:46 +02:00
Igor Zinken
c13cd6812d Add corner handles to rectangular selections to allow pointer based resizing (#95)
Working with selections on touch screen devices (especially phones) is very cumbersome to get right.

This changeset introduces corner handles for rectangular selections. Once a selection is created, each corner has a handle from which the selection can be resized.

This also addresses a state history bug when stepping through changes to selections.
2026-04-24 19:18:11 +02:00
Igor Zinken
abc5c7f1a3 When dragging a Layer with an active Selection, the Selection content should be cut and dragged as a new Layer (#94)
When the DRAG tool is active while there is an active selection, when dragging starts, the contents of the selection should be cut from the currently active Layer and be pasted as a new Layer, which will continue the drag.
2026-04-22 18:24:07 +02:00
Igor Zinken
a6f67ad7c5 Image export settings are now stored inside the Document 2026-04-19 21:28:38 +02:00
Igor Zinken
b205a553d9 Restructure document model, factories and actions (#93)
Split `definitions/document.ts` into unique files per actor type.
Create `model` folder to store the above types, their factories and the state changing actions.
2026-04-19 20:34:06 +02:00
Igor Zinken
10b2ae0d46 Address issue where carbon copy on reshuffled timeline tiles would show wrong content 2026-04-19 13:23:57 +02:00
Igor Zinken
ed03c0b745 Address issue when merging and flattening Layers in a Timeline Document (#92)
When merging a layer down / flattening the layers in a Timeline Document, it is more logical if this is done for the currently active Tile group, instead of the whole Document.
2026-04-19 09:20:25 +02:00
Igor Zinken
e916c9bd4b Allow reorder of timeline tiles using drag (#91)
Tiles in a timeline cannot be reordered after creation, which can be a little cumbersome.
Implement draggable tiles allowing the user to reorder tiles at any moment.
2026-04-18 11:04:28 +02:00
Igor Zinken
da3ae37dbd Add blur filter to Layer filters (#90)
Any good photo editing software should have a gaussian blur filter.
2026-04-12 20:00:55 +02:00
Igor Zinken
6eeed8c2bd Add support for unique state history per Document (#88)
Long overdue.

State history would only work for the active Document. When opening a new Document (without closing the existing one), the state history would be flushed and initiated anew for every change made in the currently focused Document.

This changeset introduces a state history unique to the Document, meaning you can switch between open Documents and maintain the history associated with your changes.
2026-04-11 12:30:57 +02:00
Igor Zinken
6baaaff871 Allow copy/cut/paste operations on multiple selected Layers (#87)
Simple copy/cut/paste operations were not supported for selected Layers. Further more, only a single selected Layer at a time was supported.

We now support multi select using shift + click. Copy pasting content now also works across timeline tiles for easier editing.
2026-04-08 21:39:20 +02:00
Igor Zinken
f085e19716 Add support for custom swatches 2026-04-04 12:36:47 +02:00
Igor Zinken
94b6a3c263 Update unit test mocks 2026-04-04 09:13:25 +02:00
Igor Zinken
c42cd0e662 Round selections in pixel art mode for consistency and more clear draw operations 2026-04-03 21:23:07 +02:00
Igor Zinken
40b66bb21f Rebuild all thumbnails when toggling the thumbnail display on 2026-03-28 15:07:14 +01:00
Igor Zinken
075c9f7a0d Rename action to be in line with format 2026-03-28 07:52:33 +01:00
Igor Zinken
e6ea6ea23f Sync tile cache when performing tile add/clone/delete operations 2026-03-28 07:46:44 +01:00
Igor Zinken
8acf7f4730 Add Document properties edit window 2026-03-27 21:34:59 +01:00
Igor Zinken
1712ba2068 Shuffling layer order now triggers a tile re-render 2026-03-27 19:21:04 +01:00
Igor Zinken
3999c018e9 Unified crisp pixel rendering across rendering pipelines 2026-03-27 18:12:28 +01:00
Igor Zinken
baa00dc644 Add timeline mode for animation support (#83)
### Motivation

In order to be more useful as a spritesheet editor, BitMappery now contains a timeline view, a mode where content can be sub grouped into tiles, where each subsequent tile can be traced over the previous one. Each tile can have multiple layers of content for ease of editing.

### Changes

 * Introduced Document types `default` and `timeline`
 * Introduced LayerRef types (allow grouping Layers)
 * Introduced Timeline view for tile based drawing and tracing
 * Introduced Document background color (omits need to create background layer for each tile in a timeline)
 * Cleaned up some legacy overrides made superfluous by newer dependencies
 * Added document presets to document creation flow

### Commits

* Add rel to Layer structure
* Add Document type
* Initial scaffold for timeline view.
* Added initial utility to manage timelines
* Added action to clone all Layers in a tile group
* Moved Layer cloning to layer-util
* Converted zoom tool option panel to TypeScript
* Added action to add a new tile and layer to the Document
* Added action to remove a tile and its layers from the Document
* Added Layer grouping property to Document structure
* Update type check for test
* Initial timeline panel outline
* Created tiles now match Document dimensions
* Added tile cache
* Allow showing a semi transparent carbon copy trace of the previous tile
* Add animation preview window
* Add fps control to animation preview
* Store metadata property inside Documents (allows storing timeline framerate)
* Optimise mobile view for timeline
* Keep thumbnail ratios when previewing tiles and animations
* Button and animation preview window styling
* use RAF-based animation timing in animation preview
* Changes made to layer content now trigger a re-render of the Group tile
* Update Layer reordering logic to also work with subsets
* Optimised animated GIF export, updated pixel art definitions to be more sensible
* Code cleanups
* Added background color to Documents, omitting the need for a background layer on each animation tile
* Removing temp code, updating renderer factory test
* Update layer styling, added tooltip on drag behaviour
* Added document DPI and size unit to meta data
* Refactored deprecated event property from modal key handler
* Remove unused properties from animation preview window
* Update unit test for renderer factory
* Fix bug where closing modals would trigger click on canvas
* Add presets for all Document types
* Added setting to automatically choose appropriate anti-alias setting
* Invalidate tile and thumbnail caches on resize and crop functions. Adjust spritesheet export behaviour
2026-03-26 18:47:05 +01:00
Igor Zinken
712c7abd71 Add layer preview thumbnails to layers panel (#84)
### Motivation

It'd be great if we could see a small thumbnail preview in the layers panel to more easily distinguish between layers visually.

In this changeset we introduce the thumbnail cache. When enabled, each layer is represented by a thumbnail which can be requested from multiple subscribed consumers (currently only the layer panel).

Thumbnail updates are deferred to keep CPU usage low and performance high.
2026-03-21 14:57:28 +01:00
Igor Zinken
b0e68c3fd1 When there is an active selection when a mask is created, fill the mask with the selection 2026-02-15 20:23:53 +01:00
Igor Zinken
58da943179 Prevent creating holes from subtracted selections 2026-02-15 19:29:58 +01:00
Igor Zinken
b385e61949 Support text parsing from PSD documents (#76) 2026-02-03 21:27:46 +01:00
Igor Zinken
a1ee891168 Optimizing selections: allowing merging and subtracting of overlapping shapes (#77)
* Allow merging and subtracting of selections
* Support selections with more than one other shape
* Allow subtraction using alt key
* Fix issue where stepping through selection state history would not restore merges and subtractions
* Preserve selection when switching between selection type tools
* Cleaner control of subtraction operation
2026-02-01 15:06:38 +01:00
Igor Zinken
4d1e1a8fd6 Implement color inversion adjustment filter 2025-05-14 19:45:45 +02:00
Igor Zinken
2a29dd6546 Split menu into separate reusable sections, introduced context menu actions to layer panel. Renamed tool-module to editor-module 2025-04-12 11:52:52 +02:00
Igor Zinken
bca9aa9145 When erasing content from a drawable layer, underlying layers are now preserved correctly during draw 2025-04-06 09:26:34 +02:00
Igor Zinken
f930d43078 Restructure UI, maximize layers panel when filters & effects view is opened (#66)
* Some sizing shenanigans

* Cleanups in ZoomableSprite and inheritance chain

* Ongoing

* Done
2025-04-05 11:50:08 +02:00
Igor Zinken
d64ec1ae3e Refactor Layer effects and introduce duotone filter (#64)
* Added Duotone filter to effects
* Renamed Effects actor to Transform
2025-04-04 20:55:34 +02:00
Igor Zinken
e8eb11fd06 Improve performance of dragging Masks on blended, effected Layers 2025-04-02 21:26:28 +02:00
Igor Zinken
00e0b7549a Allow committing effects and filters to a Layer source, control zoom level using pointer, move state changing actions to separate files. (#63)
* Implemented new commit layer effects and transforms action
* Moved all actions out of the application menu component
* Grid to layer slicing moved out of component
* Unified all layer filter toggling into single action
* Moved all layer panel history interactions to separate action files
* Moved mirror, rotation, later addition and document resize state actions to separate files
* Adjust behaviour of layer addition action
* Moved canvas resizing history action to separate file
* Move interaction pane selection logic into separate files
* Move layer positioning utilities to separate actions
* Use correct event variable in ZoomableCanvas
* Zoom tool now responds to clicks and alt+clicks when zoom is selected
2025-04-02 19:21:28 +02:00
Igor Zinken
641828c035 Move history management functions out of layer renderer and into history utility (#61) 2025-03-29 07:43:47 +01:00
Igor Zinken
26d7fe6593 Fix issue where dragging masks on transformed layers would not respond correctly (#60) 2025-03-28 21:57:09 +01:00
Igor Zinken
e47c0dc297 Fixed bug where cropping would not update Layer dimensions appropriately 2025-03-25 22:08:26 +01:00
Igor Zinken
94cd300259 When reordering or deleting Layers in a Document using blend caching, the cache should be flushed 2025-03-25 21:52:06 +01:00
Igor Zinken
d4dac30a6c Document resize can now be undone in state history. Document crop now cuts pixels of source content 2025-03-23 11:26:55 +01:00
Igor Zinken
b765404704 Update to clipping context while drawing 2025-03-16 12:17:59 +01:00
Igor Zinken
dbafae9984 Clip brush lines while drawing on an offset or transformed Layer 2025-03-16 12:14:31 +01:00
Igor Zinken
630ba35b40 Restructure and rename actor/renderers (#57)
* Restructure and rename actor/renderers
* Rename cache flushing functions to reflect their scope
* Move canvas instance management to dedicated service
* Type resize-canvas-window Vue file
2025-03-16 11:32:42 +01:00
Igor Zinken
5b79291faf Moving some functions out of class instances to more logical utilities 2025-03-16 07:18:18 +01:00
Igor Zinken
cc2ace1719 Restructure test mocks 2025-03-15 22:09:07 +01:00
Igor Zinken
e39317e47a Fix issue where eyedropper tool would lose accuracy on HDPI screens 2025-03-15 22:04:27 +01:00
Igor Zinken
875edf0d10 Improved performance of selection copying 2025-03-15 11:31:17 +01:00
Igor Zinken
83d8e7af4d Address issue where drawing operations on offset, cropped Layers would not use correct coordinate space 2025-03-15 10:19:27 +01:00
Igor Zinken
9ca9bbb732 Copying selection content onto new Layers reuses the original selections Layer type 2025-03-15 09:53:07 +01:00
Igor Zinken
1d37781855 Prevent drawing outside of the mask on non-graphic Layer types 2025-03-15 09:21:26 +01:00