Sometimes I need to have a container centered, while do not want to use specific width/height value.
But I find that PIXI#Container (or DisplayObject in fact) doesn't have anchor, so how can i make it centered without width/height ?
or, is it possible to write a .setPosition(w, h) method, whose w/h ranges between 0-1 ?
"anchor" is a concept for textures only; Containers and Display Objects do not have textures so do not have this property. Instead, you can use the property "pivot", which works on pixel values rather than percentages.
Example: https://pixijs.github.io/examples/#/basics/container-pivot.js
@themoonrat Thank you! I've solved my problem!
since many people ask about this question, look at the code below :
class MyContainer extends PIXI.Container {
_anchorX = 0;
_anchorY = 0;
set anchorX(value) {
this._anchorX = value;
this.pivot.x = value * this.width / this.scale.x;
}
get anchorX() {
return this._anchorX;
}
set anchorY(value) {
this._anchorY = value;
this.pivot.y = value * this.height / this.scale.y;
}
get anchorY(){
return this._anchorY;
}
}
Then the only thing you need to do is to is to update it the pivot everytime you change the affective ones (width, height, scale.x, scale.y) you can do so by
myContainer.anchorX = myContainer.anchorX;
or you can add something like that inside MyContainer class:
refershAnchors(){
this.anchorX = this.anchorX;
this.anchorY = this.anchorY;
}
I personally override the setters and getters for height, width, scale.x, scale.y inside MyContainer class
@msqaddura partial solution, we cant include it into library but of course I'm all hands for that kind of hacks if people want to use them.
The problem is in width and height. Those getters have side effects.
@ivanpopelyshev I can't but agree with you, the solution is partial and hacky (if we consider the given code)
the idea is just shed the light on how to calculate the the pivot on 0..1 basis, like an anchor. and that we have to do this.pivot.x = value * this.width / this.scale.x; i will refer to it as snippetX
By my side, I am using twin design pattern between my class and pixi classes (DisplayObjects) hence writing the code i use wont help us here. However, I will explain how to port the functionality to Pixi.
Let us first keep in mind these rules:
1) width does not change, instead it scales by the factor of difference between current width and new width, same applies to height, in code below (plus my modification) :
set width(value) // eslint-disable-line require-jsdoc
{
const width = this.getLocalBounds().width;
if (width !== 0)
{
this.scale.x = value / width;
}
else
{
this.scale.x = 1;
}
this._width = value;
//we add this line here because we alread know that scale.x is changed by now
// snippetX
this.pivot.x = this.anchor.x * this.width / this.scale.x;
}
scale also changes if developer wants to scale a DisplayObject implicitely. Since it is a Point (if am not wrong) , we can use ObservablePoint instead and in the callback we call snippetX.
now as well, anchor itself might change so we need to apply the same snippetX to anchor.x (ObservablePoint?)
backward compatibility ;( if someone is using the pivot in his code already, and we introduce this change then pivot will conflict with anchor. unless then we put a flag to use pivot XOR anchor
That is why in the first place i did not want to explain it in details, i believe it is just better to shed light upon pivot=anchor*width/scale. In my case I completely disabled pivot and this is how my code looks like
class Entity {
//only code related to this question
_anchorX = 0;
constructor(){
this.pixiTwin = new Pixi.Container();
}
get anchorX(){
return this._anchorX;
}
set anchorX(value){
this._anchorX = value;
this.pixiTwin.pivot.x = this.pixiTwin.width/this.pixiTwin.scale.x * value;
}
}
Illl just reference your post in pixi wiki under "Gotchas" :) I like those little snippets.
Done, look at https://github.com/pixijs/pixi.js/wiki/v4-Gotchas
Thanks! :)
I hope this will other developers get around this question
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.
Most helpful comment
"anchor" is a concept for textures only; Containers and Display Objects do not have textures so do not have this property. Instead, you can use the property "pivot", which works on pixel values rather than percentages.
Example: https://pixijs.github.io/examples/#/basics/container-pivot.js