Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds some stage UI for editing an NSlicer, including adding axis and changing tile modes. The inspect panel's UI still needs some work. ### Structures added 1. I added an NSlicer Editor that takes after vertexEditor. You can only edit axis when the NSlicer is solo'ed. One behavior that's different is that if an axis/tile is selected, escaping won't immediate escape the solo mode. Instead, it'd just deselect everything. 2. The StageNSlicerAxis represents an Axis component. However, StageNSlicerAddAxis has no component. 3. It's just an UI that kind of looks like a StageNSlicerAxis but when dragged, it immediately creates an StageNSlicerAxis. 4. StageNSlicerTileMode isn't backed up by a component by default, but is manually initialized if there happens to be an NSlicerTileMode in core. So in a way, these three stage items all are slightly different. ### A note on creating bounds The trickiest part to this PR imo is making sure the bounds of the axes and the tiles are calculated correctly. StageNSlicerAxis and StageNSlicerTileMode both use the image's world transform and the artboard's world transform to calculate its space. When dragging an axis, the mouse diff in image space isn't necessarily how much to change the Axis.offset by. [Here's a thread](https://2dimensions.slack.com/archives/C07D9AE1ZRV/p1725582977896249) that explains the problem. When an axis is dragged, other stored axis will also move their screen position. This data is represented in a new editor-only field called `offsetInLocalSpace`, and is updated by NSlicer on dirt. There's one hack with the AABB. You can find it be searching 'hack'. Details [in this slack thread](https://2dimensions.slack.com/archives/C07HQ4GS0BH/p1726089308629329). ### Some edge cases 1. I made sure to handle tiling for axes that are very close to each other (or even 0). Previously I think it'd run past 1m iterations. Now, I make it early exit and not bother tiling for really small patches. I wrote a test for this. 2. I also handled a case where if all axes are paired up to be the same, then we still try to keep the fixed patches fixed, but stretch the zero patches so the bounds of the image stay the same (find 'emptyScalableSize' for this logic). This doesn't really serve a practical purpose. Another way to handle it could be to treat it as if there's nothing set so it'd just be the unscaled image, but I thought this implementation looks better. Demos for these edge cases, also demo'ing it works in Runtime. ![handle-zeros](https://github.com/user-attachments/assets/4fe6dfef-caa3-4abd-b89d-7b59012903ff) TODO: https://www.notion.so/rive-app/N-Slicing-10622b943b2f4a8e90a78af7f1e0be07 More on N-slicing: https://www.notion.so/rive-app/N-Slice-Tech-Proposal-Image-only-50b25ea8e79c4efabb681110e288f064 ### Demos: Adding an axis ![aaapr-stage-add-axis](https://github.com/user-attachments/assets/5a12def9-802b-4a83-90a6-0b4cf97e8668) Deleting via backspace ![aaapr-stage-delete](https://github.com/user-attachments/assets/5e608321-12aa-424b-9152-4fd50cdddf55) Dragging an axis ![aaapr-stage-shadow-line](https://github.com/user-attachments/assets/375ee90a-a867-4f75-b8f6-4f1b068a43f8) Toggling tile modes ![aaapr-stage-toggle-tile-modes](https://github.com/user-attachments/assets/d593abb1-d206-43b1-a480-bd0de97c2ec1) Diffs= 95e58ca40 editor: Stage UI for N-Slicing (#8136) Co-authored-by: Susan Wang <[email protected]>
- Loading branch information