Giedrius

possible to tell pixi to render children which are not in Container.children array?

Recommended Posts

You could always have 2 containers and add them to your maincontainer. Container1 would have your containers children and then the second content array would be in container2. And then you maincontainer would consist of container1 & 2.

Or if you want to render the list of children instead of containers children, then you can just swap the children-list into new one.

Share this post


Link to post
Share on other sites

Its one of often-used hacks.

Yes, you have to override `render` and `renderAdvanced` methods, please look inside container source:

https://github.com/pixijs/pixi.js/blob/dev/packages/display/src/Container.js#L488

https://github.com/pixijs/pixi.js/blob/dev/packages/display/src/Container.js#L519

If you dont have masks and filters then just overriding `render` will do fine.

Beware that you also have to be sure that updateTransform is called if those elements are out of the tree, call it for detached subtree.

Also there's a plugin that allows to have "dynamic" children in container, just specify "element.parentLayer = layerToRender" and element will be rendered inside a particular layer container: https://github.com/pixijs/pixi-layers/ Of course it has a few lines of setup, make sure you read README and satisfy the conditions.

Share this post


Link to post
Share on other sites

Thank you guys for suggestions, appreciate that! I would like to try to override render method, but not sure how to do it. I am extending Container class, so if I copy render code there, it yells at me that this.renderAdvanced, this._render does not exist.

export default class Row extends Container {
constructor() {
super();
}

render(renderer) {  // ?

}
}

 

Share this post


Link to post
Share on other sites

I am using pixi-v4, I mean if I copy all the render method from Container:

export default class Row extends Container {
constructor() {
super();

}

render(renderer) {
        // if the object is not visible or the alpha is 0 then no need to render this element
        if (!this.visible || this.worldAlpha <= 0 || !this.renderable) {
            return;
        }
        // do a quick check to see if this element has a mask or a filter.
        if (this._mask || (this.filters && this.filters.length)) {
            this.renderAdvanced(renderer);
        }
        else {
            this._render(renderer);
            // simple render children!
            for (let i = 0, j = this.children.length; i < j; ++i) {
                this.children[i].render(renderer);
            }
        }
    }

}

this.renderAdvanced(renderer);  ->  property renderAdvanced does not exist on type Row;

this._render(renderer);  -> property  '_render' does not exist on type Row

 

My goal is to override that method and to use it only for Row object rendering? If yes, then how do I do it? :)

Share this post


Link to post
Share on other sites

I gave you link to v5 source. For v4 use https://github.com/pixijs/pixi.js/blob/v4.x/src/core/display/Container.js#L394

Its important to look in the sources, you cant do hacks without them. That kins of hacks are normal in pixi because we are very small team and we can't possibly document all that stuff and give people API and examples on every minor idea.

Please dont treat pixi like a black box.

Share this post


Link to post
Share on other sites

Thank you! what I did is:

export default class Sector extends Container {
constructor() {
super();
}
renderWebGL(renderer) {
        // if the object is not visible or the alpha is 0 then no need to render this element
        if (!this.visible || this.worldAlpha <= 0 || !this.renderable) {
            return;
        }

        // do a quick check to see if this element has a mask or a filter.
        if (this._mask || (this.filters && this.filters.length)) {
            this.renderAdvancedWebGL(renderer);
        }
        else {
            this._renderWebGL(renderer);

            // simple children!
            for (let i = 0, j = this.children.length; i < j; ++i) {
                this.children[i].renderWebGL(renderer);
            }

            // simple rows children!
            for (let i = 0, j = this.childrenRows.length; i < j; ++i) {
                this.childrenRows[i].updateTransform();
                this.childrenRows[i].renderWebGL(renderer);
            }
        }
    }

and I got those childrenRows rendering on the screen, but I think it's not updating on every stage transform (zooming in out) now and parent container is not the same with/height as it used to be. I had to set parent property for row objects to be able to updateTransform, and do I need to set _parentID = -1 to ensure child transform will be recalculated? The problem is that _parentID is protected and only accessible within TransformBase class. so I am stuck and asking for help again  😐

Share this post


Link to post
Share on other sites

Yes, that's correct. just "as any" it. PixiJS v5 typings are different btw :)

i actually recommend to add all those rows somewhere else, if they dont have parent. Just make a temp parent that you updateTransform() before render

I see that you understand the code and im sure you'll get it working.

Share this post


Link to post
Share on other sites

Thank you Ivan, I got it working and I need those rows to belong there unfortunately. Now I face another chanllenge - I need include those childrenRows in bound calculations also. What I did is I've overridden the calculateBounds method: 

calculateBounds() {
        this._bounds.clear();

        this._calculateBounds();

        for (var i = 0; i < this.children.length; i++) {
            let child = <any>this.children[i];

            if (!child.visible || !child.renderable) {
                continue;
            }

            child.calculateBounds();
            this._bounds.addBounds(child._bounds);
        }
        for (var i = 0, l = this.childrenRows.length; i < l; i++) {
            let child = <any>this.childrenRows[i];
            if (!child.visible || !child.renderable) {
                continue;
            }

            child.calculateBounds();
            this._bounds.addBounds(child._bounds);
        }

        this._lastBoundsID = this._boundsID;
    }

but now my bounds calculation depends on zoming level. If I zoom in, the bounds are much larger than they should be. I am calculating bounds on that Sector Container with  rect = this.getLocalBounds(); Did I miss updating transforms of  childrenRows?

Share this post


Link to post
Share on other sites

Yes, I did miss updating transforms - I've override the updateTransform() method and everything works fine now:

updateTransform() {
        this._boundsID++;

        this.transform.updateTransform(this.parent.transform);

        // TODO: check render flags, how to process stuff here
        this.worldAlpha = this.alpha * this.parent.worldAlpha;

        for (var i = 0, j = this.children.length; i < j; ++i) {
            let child = this.children[i];

            if (child.visible) {
                child.updateTransform();
            }
        }

        for (var i = 0, j = this.childrenRows.length; i < j; ++i) {
            let child = this.childrenRows[i];

            if (child.visible) {
                child.updateTransform();
            }
        }
    };

 

Share this post


Link to post
Share on other sites

Now I am working on another puzzle - to make children interactive I used to set interactiveChildren flag. Now how do I make the same for children in custom array? I found a method processInteractive  in InteractionManager.js which seems to be responsible for that, but how do I override it ? 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.