New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: 3 properties to manage object positioning #997
Comments
👍 x 1000000 because we really need this. 1 question: Which point would the anchor attach to? origin, or an internal value? |
Hmm. What are the pros/cons for normalized positions versus pixel positions? For me, pro: A pixel position is easier to understand, though (con) less portable. "(1, 1) is top-left of the texture is on the bottom-right of the object." |
@photonstorm I said in the proposal that the anchor attaches the texture to the top-left of the object, but I am open to it attaching to the origin instead @agamemnus I definitely disagree that a pixel position is more clear, remember we are talking about a world pixel position, not a local position (that is how it works now). A normalized position is portable, has to be normalized eventually anyway, and makes sense in this context (and what players are used to for anchor now). |
This is perfect! ✨ |
I think that for some cases, a pixel position makes a lot more sense. Consider the use case of orbiting: the pivot is outside the object's bounds and in all probability attached to some sort of object. The proposed normalized pivot would necessitate determining that object's relative normalized position in respect to the orbiting object, which sounds like a huge mess to me. Perhaps what's necessary is a range of helper functions to easily access global/local pixel values? |
From my experience pixel values are easier to understand but normalised values are easier and more convenient to use. Very often I set anchor to (0.5, 0.5) and I don't care about size of a sprite. My opinion is based on comparison between Starling (where you have pixel values) and PIXI.js. |
Hey peeps, The main reason I have avoided using normalized values (outside of texture alignment) is that it requires knowing the dimensions of the object at all times. Calculating the widths / heights of all objects on the stage each frame would add an overhead to the rendering loop that would impact performance :/ I'm thinking we could rename |
@englercj I only asked where it'd align because if you adjust where the top-left of the object is, would it work in relation to that or the actual real un-modified top-left? :) I much prefer working with normalised values, I just find them easier to deal with in our responsive games. Although I've lost count of the number of times new phaser devs have been puzzled by them :) |
Unless there are tens of thousands of sprites with pivots and so on, in my opinion, performance wouldn't really be an issue... it is just some multiplication... right? |
It's quite a lot of calculations: https://github.com/GoodBoyDigital/pixi.js/blob/dev/src/pixi/display/Sprite.js#L163-L234 - every frame, for every object. I'd imagine the depth of the display list is almost as important as the size in this case, as everything propagates. |
@photonstorm is correct :( we would need to essentially transform all children of the an object to its local coord system and then measure each object to calculate the min max values. Then we would need to transform them again to the global coord system. |
What about a global setting deciding which way the developer wants? If it doesn't add too much work. |
I don't catch the difference between Orgin and pivot. I think we need only two points.
I'll try to implement a new kind of DisplayObject, a Frame, that is invisible, but serve as a guide to position siblings. We should get rid of thinking in pixel. We are in the era of mixed display format, mixed resolution, mixed PPI (retina display). If we want to easely manage textures and change texture set according to resolution/PPI/bandwith of target we have to work in normalized values. Like GPU does. Modern engines like UBIart Framework are floating point based. Time changes |
@GoodBoyDigital: The way other frameworks solve the performance issue is by offloading the responsibility of maintaining sizes updated to the programmer. The basic idea is to expose a
It's important to note that the function to update the size and the functions to get the bounds are not the same, there are cases in which the programmer might wish for an object to maintain a size while moving the object's children arbitrarily, think of elliptical orbiting for example, the effect could be achieved as follows:
That will effectively make Another advantage of this approach is that The biggest issues with this approach are (1) that it increases the amount of work needed to setup your objects and (2) that if it is more convenient for an object's size to be updated constantly now the programmer needs to keep track of which object is that and manually update its size every frame. To solve issue (1) we need to solve issue (2) first. In real use cases most objects will not need to have their sizes updated every frame because most objects are sprites or simple objects, with that assumption in mind then we can create an
Obviously the code would have to be cleaned up and really thought through, I wrote this implementation from the top of my head. Once we have an With all that said, this might not be the best solution to the problem, but I believe it should be considered. |
Nice! Thanks for sharing this @darionco ! I Will get back to ya soon with my thoughts! 👍 |
I'm maybe weird but I actually like how the pivot property works now... :P
And I don't really see the point of making it different, could it be less code/more readable? |
+1 |
+1, pivot is awkward to use and I have yet to get it working, an origin is a must in my opinion. |
As a follow up to this @englercj you suggested (0,0) to be top left and (1,1) to be bottom right for the origin, what if I have a map and I want to zoom in on whatever the cursor is pointed to. This would not work with such low granularity. What about a pixel based origin? e.g. 500 x 500 rectangle, if I point to an object at 250x and 375y the origin would be (250,375). From there a scale transformation would respect that origin and zoom as intended. |
In Javascript, numbers are 64-bit floating-point IEEE numbers. The precision limits are the same regardless of the scale. Anyway, in terms of map zoom, you can handle this by setting a scale and offset value on a DisplayObjectContainer. |
@agamemnus |
My bad. I was calling it a stage in my code but it's actually a DisplayObjectContainer. |
@agamemnus see that is what I have done but there is no offset. I am having to set the pivot and then the scale of the DisplayObjectContainer, this gets complicated though. As you zoom in 0,0 of the mouse is no longer 0,0 of the DOC, it is now 125, 125 depending on how much you zoomed in. I am having issues accounting for this numerical transformation. |
I see. Maybe my code snippet can help you.
|
What does the Also what is your Lastly it seems that you don't apply these variables to a DisplayObjectContainer, can you elaborate. Would I just do |
content_div is a centered You can see it in action here (Chrome only atm): http://tinyurl.com/llpn4hn |
Eh, I can see it working for you but am still unsure about many things like |
container.scale = scale rect.left and rect.top are typically 0, I think. The important part is:
|
@agamemnus I ended up getting it, code isn't the prettiest right now but it works. I will post my solution once I have things looking decent. |
@agamemnus and everyone here, you can see my implementation as a stand alone repo over here: https://github.com/Arduinology/Pixi-Pan-and-Zoom |
Great. Don't forget to add a license text or file (MIT is typical) so people can potentially use it. |
Thanks, added. |
Closing this one peeps. This seems like it could make a nice plugin for v3 though if anyone fancies the task! Cheers! 👍 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Proposal
I propose, there should be 2 properties on a DisplayObject:
origin
andpivot
; and one extra property on a Sprite:anchor
. These properties are defined below:Origin
The
origin
would be a normalized point that describes where the position of the object is oriented.(0, 0)
means the position of the object describes the top-left of the object,(1, 1)
means the position describes the bottom-right of the object.Pivot
The
pivot
would be a normalized point that describes the point at which the object rotates around. Again,(0, 0)
is top-left,(1, 1)
is bottom-right.Anchor
For sprites, there is an extra property
anchor
. This is in addition to the previous properties that it inherits from DisplayObject. Theanchor
is a normalized point that describes where the top-left of the texture attaches to the object.(0, 0)
is top-left of the texture is on the top-left of the object,(1, 1)
is top-left of the texture is on the bottom-right of the object.Conclusion
With these three properties you have the ability to do anything you need to with regard to positioning and rotating. It also reduces ambiguity that comes from having pivot be a pixel position, and anchor be normalized. Many issues arise from having the current implementation of
pivot
be a hybrid of the proposedorigin
andpivot
and even more so fromanchor
being used to fill that gap. This solution clarifies the use of each property, removes ambiguity, and adds additional functionality.The text was updated successfully, but these errors were encountered: