Yellow-Dog-Man / Resonite-Issues

Issue repository for Resonite.
https://resonite.com
139 stars 2 forks source link

UIX: Allow visually rotating elements (without affecting layout flow) #1516

Open JackTheFoxOtter opened 7 months ago

JackTheFoxOtter commented 7 months ago

Is your feature request related to a problem? Please describe.

Currently, UIX does not provide the ability to rotate individual elements in 2D.

Describe the solution you'd like

A way to specify rotation values for UIX elements on a canvas.

Describe alternatives you've considered

Using nested canvases and rotating those. Not ideal.

Additional Context

No response

Requesters

No response

shiftyscales commented 7 months ago

Can you please provide additional context on what you are trying to build, @JackTheFoxOtter?

JackTheFoxOtter commented 7 months ago

UIX canvases with rotating parts. This is a very general purpose request, but some specific examples I can think of:

BlueCyro commented 7 months ago

While potentially not what you're asking for, you can achieve these effects with nested canvases. When configured correctly, they behave as part of the main canvas in terms of how they render. I realize you mentioned those in your post, but how come they aren't ideal?

5H4D0W-X commented 7 months ago

Nested canvases are mentioned under the "alternatives you've considered" section. There are problems with those setups though, especially because RectSlotDrivers don't always update correctly and do not respect UnitScale.

BlueCyro commented 7 months ago

Nested canvases are mentioned under the "alternatives you've considered" section. There are problems with those setups though, especially because RectSlotDrivers don't always update correctly and do not respect UnitScale.

I feel like those are issues that should be tackled then instead of having a feature that circumvents them

Frooxius commented 7 months ago

I think this is worth having as a feature. NestedCanvases are somewhat heavier, so if you need to rotate lots of pieces of the canvas, they'll have too much overhead, over native rotation support.

One part that is however kinda weird, is how exactly would this actually work with the "flow". We can flow the elements as normal and the rotation will essentially "ignore" the layout, it happens after the UIX has already been laid out.

If we wanted the layout to respond to the location - e.g. with content size fitter, this makes this significantly more complex, because now the layout algorithms have to consider that the children can be rotated. If some layouts grow (or are constrained) only in a particular dimension, now they need to grow/be constrained in multiple.

JackTheFoxOtter commented 7 months ago

I was thinking about this as well, and decided to leave it out of the original request because I'm just not sure what would be a good approach. I could work with every solution, including not affecting layouting at all.

One thing I was thinking could maybe be a good compromise is using the element's axis aligned 2D bounding box as a basis for layouting, which I assume could be much easier to implement. This would work pretty well for any element that's rotated in 90 degree intervals, but be a bit weird for everything in between, especially animated elements, as the bounding box would grow & shrink as the element rotates.

5H4D0W-X commented 7 months ago

I think it should use the bounding box approach by default, with a new sort of tag component that tells the layout to ignore the rotation and use the actual size of the rect instead of the bounding box. It would also be neat to have an option to have the bounding box respect sprites so that the bounding box rolls over rounded corners correctly. Another important think to think about with rotation is pivots. Will a rotated rect use its own pivot or the pivot of its parent?

Banane9 commented 7 months ago

The most common thing imo would be rotating "square" images I think, where the easiest way to deal with the bounding box would be to keep it static so it rotates in place 🤔

JackTheFoxOtter commented 7 months ago

The most common thing imo would be rotating "square" images I think, where the easiest way to deal with the bounding box would be to keep it static so it rotates in place 🤔

I disagree, the most common thing would likely be rotating text, which is almost never square. Maybe there could be a setting for the "handling" of layout bounds. Either "keep" to keep the unrotated bounds or "compute" to compute the axis aligned bounding rectangle of the current element. I can see both as being useful in different situations.

Frooxius commented 7 months ago

The main question is what are your use-cases for this? Because some might benefit from the flow bounds being stationary pre-rotation and being only visual, while others might benefit from the layout being aware of the rotation.

The rotation being only visual is significantly simpler to implement. If it's sufficient, we could do that first and do layout-aware one later if needed.

For the awareness of sprites - that's very unlikely to happen, because this would get very performance expensive very fast - you'd need to traverse the sprite pixels to find the bounds for each rotated element - and you can't do just edges, because you don't want any of the sides overlapping either. If you want it to respect rounded corners and such, I'd just leave that up to implementer to do the math for that one.

5H4D0W-X commented 7 months ago

if totally necessary, I guess people could do "manual" math to compute the rotated bounds and drive the size on a LayoutElement. I can't think of any specific use cases for rotated bounds anyway

JackTheFoxOtter commented 7 months ago

Purely visual rotation on its own is gonna be very useful already, that would solve what I wanted to do with them in my immediate use-case (just animating background effects in my case). Use-case for layout-aware rotation is definitely text. Vertical text is something you currently cannot do natively in UIX. With visual rotation alone you can, but that could make flow weird, you'd basically be guaranteed to have elements overlapping unless you use static heights in a container above the text. Which - again - would already be MUCH better then no rotation at all - but I do think an option for layout aware rotation would be useful for the future. I could make a separate ticket for that once we have visual rotation tho, so let's focus this request on visual rotation only first.

Banane9 commented 7 months ago

That would also make the "refresh" button animation I have on the spotify panel significantly easier, only having to rotate the sprite, rather than animating it.

Psychpsyo commented 7 months ago

I've had a use-case for this in the past that didn't need rotated bounds either. Also, coming from CSS, I'm used to transforms like this not affecting the flow of the UI and being purely visual. I don't think I've ever had that be a problem there either.