Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.85k stars 819 forks source link

Proportionally scaled corner's dimensions in 'scale9Grid' #888

Closed Liklainy closed 8 years ago

Liklainy commented 8 years ago

When migrating from 1.8 to 2.0.1 Scale3Image is replaced by Image with scale9Grid. Feathers's migration guide suggests that it should be done like this: screen shot 2016-08-06 at 19 30 53 "For horizontal scaling, set the grid's height to the full height of the texture" But when scaled vertically it's behaviour is not the same as Scale3Image. Got: screen shot 2016-08-06 at 20 03 49 Wanted: screen shot 2016-08-06 at 20 03 19 So this grid is not what i wanted, and i think the right grid should be like this ( with height == 0 ): screen shot 2016-08-06 at 19 31 12 But when an image with this grid is scaled vertically texture coordinates are messed up. screen shot 2016-08-06 at 20 53 01 I tried to fix this by adding proportional scaling for corners.

PrimaryFeather commented 8 years ago

Thanks a lot for the pull request! That's definitely a useful addition, and I appreciate your efforts! :smile:

I'll look into your implementation as soon as I can! Unfortunately, there's a lot of possible side effects in scale9-grids (you probably noticed that yourself when looking into the code; especially the texture frame is evil), so I need to check this thoroughly. Thanks in advance for your patience!

PrimaryFeather commented 8 years ago

I could squeeze this in today! :smile:

So, when I had a look at the problem, I noticed that you actually fixed two problems here:

  1. That certain grid / scale combinations messed up the texture coordinates
  2. That it was not possible to use the Scale9Grid identical to a Scale3Grid, with proportional scaling.

When I looked into problem (1), I decided that the best (most easy to read) fix would be to unite the two calls to setupScale9GridAttributes. So I did that.

Then, when I wanted to merge in your pull request, I noticed that I could greatly simplify the logic for (2) when using the logic proposed by Josh (what he recommends doing in the migration guide you mention). It's now a very simple if-else construct (just 4 lines).

And given that the complexity of the scale9grid calculation is extremely high, anyway, I decided that I'd better favor the simplest possible solution here.

In any case, that change now makes it possible to use the scale9Grid in an identical way to Feather's old Scale3Image. You just have to use the full height/width of the texture.

I hope you are fine with that! Without your pull request, I probably would never have seen this solution. So thanks again!!

Please try it out and tell me if that works for you, or if I maybe overlooked anything.

Liklainy commented 8 years ago

Thank you! This will work with the grid proposed by migration guide. But I believe scale9Grid should behave a bit different: the proper behaviour for scale9Grid would be to not scale the corners unless the middle part's height is zero and the desired image size is less than the sum of corner sizes. In that case the corners should be scaled proportionally along both axes. Please, consider these two examples: grid_1: and grid_2: result_1: and result_2: my goal was: grid_1 -> result_1 and grid_2 -> result_2 your fix gives: grid_1 -> result_2 and grid_2 -> result_1

Here is another example with a more general case: With the current implementation corners are not scaled proportionally: As opposed to proportional scaling (what I tried to fix):

To sum it all up:

  1. I believe that the proposed grid is not the right choice for Scale3Image replacement;
  2. the corners, if scaled, should be scaled proportionally with every grid.
PrimaryFeather commented 8 years ago

Your arguments are very convincing; I see the advantages in your approach!

There's only one problem I'm having: in the very bottom of your sample movies, when you'd move the mouse even further down, the corners would start to become bigger than their original size, right? The object would more and more look like a circle. (That happens when I try it out, at least.)

And isn't that exactly what you want to avoid when you're using a Scale9 grid? I'd expect it to become a bigger and bigger rectangle with uniformly rounded corners instead. With your code, I can only achieve this when scaling it horizontally, not vertically.

In other words: I think we're seeing a third issue here:

By fixing (3), the grid would act just as you want it to when scaling it below a certain size. I still think we need (2), though - just so that there's a way to use the property just like a Scale3 grid, which is supposed to scale up the caps. We just don't want that to happen all the time.

Does that make any sense? :wink:

PrimaryFeather commented 8 years ago

The object would more and more look like a circle.

I just noticed that this only happens (in your version) when the center element of the scale9Grid has a height of zero. With, say, 1 (as you described yourself), this doesn't happen.

Is that happening on purpose?

Liklainy commented 8 years ago

I will explain why you got this result with the grid you used (you didn't mention which one). Here is the image which i use in examples: ___scale3 Grids:

Grid_1 - grid proposed as Scale3Image replacement

Grid_2 - grid, which should be Scale3Image replacement

Grid_3 - common grid for scale9Grid

Vertical scaling for these grids:

current implementation:

my approach:

Result which you got from scaling vertically can be seen only with Grid_2.

I believe scale9Grid should behave like this:

  1. When resizing an image, middle parts (the middle column / row) should be scaled if they exist. In the Grid_2 when setting height to zero I'm saying that the middle part doesn't exist, like there are no pixels which can be scaled.
  2. corners don't have to be scaled. They could be scaled only when there is no middle part. And there are no middle parts if desired image size is less than the sum of corner sizes ( might be already scaled ) or if we explicitly state that we omit them (i.e. set its width/height to 0).
  3. when at least one middle part is present then corners should be scaled proportionally along both axes. If there are no middle parts at all we should scale them independently along each axis.

Scale3Image grid Scale3Image behaviour

PrimaryFeather commented 8 years ago

Wow, thanks for the detailed analysis and description!

There's one thing where I disagree: when I see the following two grids, I would intuitively expect them to lead to almost the same output.

grids

Just because the center row has a height of zero does not mean (to me, at least) that there is no content to display. To me, this describes the intent: "stretch the adjacent pixels from the top and bottom rows in this area".

Now you might argue: It's also not intuitive that having a zero-height top and bottom row (the current approach) suddenly leads to proportional scaling of the caps. Agreed!

So both approaches need to be documented. In my opinion, none of them is more intuitive or "right" per se. It's just a matter of definition.

However, I think there's one downside in your approach. It would break some existing code, namely code from people who (like me) didn't think that the zero-height center would be any different than a one-pixel-height center. In other words: there is probably some code out there that uses a zero-height center, but wants a true scale9 grid (not a scale3 grid). Those developers would now suddenly get circles instead of rounded rectangles.

The side effects of the current implementation are slightly less severe, since it always only fixes objects that were previously distorted. And it only affects people who were looking for a scale3 grid anyway (because there's no other way to interpret a grid with a full-height center).

Do you see what I mean?

It would also be interesting to know how other frameworks handle those grids.

Thanks for the fruitful discussion, by the way! And if anybody else wants to chime in, I'd be happy to hear what others think about this.