Jump to content

Is there any virtual dom library which could work with pixi dom?


user471
 Share

Recommended Posts

>Not sure what you're really after

I am looking for universal virtual dom library(compare two virtual doms, patch real dom, etc), which could work with any dom and in particular with pixi.

 

>Pixi has a scenegraph but it isnt DOM.

What is the main difference? For me both are just a tree of objects.

Link to comment
Share on other sites

React have made great strides in generalised their diffing algorithms to work away from actual HTML DOM elements, effectively meaning any scene graph can be stuck on the front. React-pixi makes use of this so that pixi becomes the end target rather than creating HTML elements, more info here. React is a bit more than just a diffing algorithm though and I dont think it will be trivial to strip all the other stuff away.

 

Things like this vdom module expose their parts so you could probably strip away the HTML stuff fairly easy and reuse the tree building and diffing stuff. You'd just need some way to diff your objects and some way to render them, I'm also not sure how easily a different library could traverse Pixi's scenegraph, sounds like you'd be duplicating objects both in pixi and in your vdom, although I guess that is how vdoms work in general, although its necessary with HTML elements and probably not so with Pixi objects. Ach, thats implementation anyway.

     

  >Pixi has a scenegraph but it isnt DOM.

  What is the main difference? For me both are just a tree of objects.

 

My bad, browser DOM exposes a scene graph, I should have said that Pixi doesnt render to HTML.

Link to comment
Share on other sites

>although its necessary with HTML elements and probably not so with Pixi objects.

Why do you think so? There are two ways

1) Recreate whole Pixi scene every time

2) Patch the scene, with some changes (but the cost is you need to create vdom and use diff algorithm)

If I am correct, Pixi is using some object caching and second option should be in theory much faster.

Link to comment
Share on other sites

>1) Scene graph, no relation to DOM at all. No attributes, no content.

What do you mean no relation to DOM?

For example, when you create Text Node it create canvas

function Text(text, style, resolution){    this.canvas = document.createElement('canvas');    ...
Link to comment
Share on other sites

I'm up to join the philosophical debate ;)

 

A webpage without scripting is still a webpage; the DOM is a tree like hierarchy that exposes a document's description and parts to scripting. The DOM is an interface to a browser's internals exposed to script; and it benefits from wrapper libraries to smooth over differences between implementation and quirks.

Pixi.js is a javascript library, itself it wraps a small potion of the DOM to provide a retained mode graphics library especially for 2D games. Being a retained mode library it provides a scene graph with renderable nodes such as sprites, which yes, is also a tree structure - but it is not a document nor an interface over some larger system, it is just the data-structure used to hold the common abstractions rendered by games. Though it is possible to load some limited document descriptions such as sprite sheet and bitmap font description files with Pixi.js, it does nothing without game scripting telling it precisely what to do.

Thus, there is no "DOM" manipulation for Pixi.js because there is no need for it, Pixi.js is under the game's control - save for the very limited examples of data loaded from sprite sheets and fonts there is nothing in the scene graph that the scripting hasn't asked to be there and maintains control of - Pixi might have a tree to traverse for drawing order and parent/child transforms (eg. so the arm sprite of a character can conveniently have local coordinates to the character sprite it belongs to and move with it) but the script that created those sprites should never lose track of it as the script is always responsible for the life time and interactions of that object, it can rely on Pixi only for specific functionality delegated to it, such as drawing those objects every frame.

As other's have tried to clarify what would be the point of a DOM-like wrapper for Pixi.js? What is the actual problem that you want to solve here?

Link to comment
Share on other sites

>but it is not a document nor an interface over some larger system,

I don't think so. Pixi is exactly the object model over Canvas or WebGL.

You can directly change canvas or you can use Pixi interface over it.

 

>As other's have tried to clarify what would be the point of a DOM-like wrapper for Pixi.js?

So, there is no need to create dom-like wrapper because Pixi already has DOM.

 

>What is the actual problem that you want to solve here?

The same problem that was solved by virtual dom. You don't want to think about DOM state and manually change it.

Instead you create a virtual dom and work with it.

Link to comment
Share on other sites

Text doesnt use DOM side of canvas, it just needs a bitmap and graphic context to work with. Nothing in pixi uses DOM, scenegraph is already virtual. Basically its just a tree of containers, each has its childrens.

Are you saying that both options would have a similar performance?

 

1) Recreate whole Pixi scene every time

2) Patch the scene, with some changes (but the cost is you need to create vdom and use diff algorithm)

 

Virtual DOM also need to be lightweight, because you will recreate it every change.

I don't think the pixi DOM fits this requirement.

Link to comment
Share on other sites

  1. Every pixi object is basically an affine transform which is determined by (position, scale, rotation). Its already lightweight, changes cost nothing.
  2. Every render() call is re-calculating matrices, "updating" all objects and then rendering it from scratch

I dont have to calculate diffs, because tree is re-calculating everything every frame, that's how scene graph works in modern game engines.

Link to comment
Share on other sites

 

  1. Every pixi object is basically an affine transform which is determined by (position, scale, rotation). Its already lightweight, changes cost nothing.
  2. Every render() call is re-calculating matrices, "updating" all objects and then rendering it from scratch

I dont have to calculate diffs, because tree is re-calculating everything every frame, that's how scene graph works in modern game engines.

 

Is Pixi not have any cache?

 

Also, for example I want to change text, so I can

1) Change property in existent text object text.text = "new text"

2) Destroy previous one and create new

text.destroy();

text = new PIXI.Text("new text")

Would it be the same operations, performance-wise?

Link to comment
Share on other sites

The benefit of virtual DOM is that you don't have to touch DOM that didn't change, and therefore the browser only needs to rerender things that have changed. This is an optimization because the browser updates and redraws only portions of the tree. It has dirty rectangle optimizations that draw only subsets of the final output and further optimizations in the compositor that do similar things. All this comes together to make changing as little as possible a good thing. They do these optimizations because *most* of the time a webpage doesn't change everything all the time. It changes only small parts, and only sometimes.

 

A scene graph is different, and more importantly PIXI is different. There is no dirty rect optimization, we render the entire scene every time you call render(). We update the transforms of the entire scene every time you call render(). We don't "cache" previous frame calculations because for most use cases every frame is widely different. For games this is nearly always true, but for some different cases it isn't. However, the overhead for doing those optimizations *in javascript* makes it likely they wouldn't help for the uses PIXI is generally used for (as evident by react-pixi). They may make the update phase faster (maybe not, the diff might be just as expensive) but on rendering it would be WAY more complex with multiple rect buffer and a compositor, none of which exists right now.

 

 


Also, for example I want to change text, so I can

1) Change property in existent text object text.text = "new text"

2) Destroy previous one and create new

text.destroy();

text = new PIXI.Text("new text")

Would it be the same operations, performance-wise?

 

Dear god no, they would not be the same. One changes the text which is:

  1. write to canvas,
  2. re-upload texture.

The other destroys the object and creates a new one which is:

  1. destroy text object,
  2. destroy underlying canvas,
  3. destroy the gl texture,
  4. create a new text object,
  5. create a new underlying canvas,
  6. create a new gl texture,
  7. write the text to the canvas,
  8. upload the new texture.

The second is way more work. Pixi and almost every other engine in the world doesn't pool objects for you, that is in user land.

Link to comment
Share on other sites

Man, there is a huge disconnect that seems to be going in this discussion. @chg has done the best so far in trying to address it but maybe I can help to clarify and simplify things a bit so that they click with the OP.

So to reiterate what every one else has said...with Pixi.JS THERE IS NO DOM. The canvas tag is merely a bridge between the DOM and what is essentially a dedicated viewport for graphics rendering (also called a pixel buffer). Once you plop that canvas tag down, the most you can do with it DOM-wise is to add alt text. No child elements (seriously, look up the specification). Henceforth the only way to manipulate that view port is through the API's (Canvas) supported by the browser. There is no shadow or virtual dom associated with the canvas tag, the region it describes on your screen is only for pixel level manipulation.

 

So once you do this:

this.canvas = document.createElement('canvas');

You essentially kiss the DOM goodbye. You're dealing with a graphics context from here on out.
 

Now there are Javascript APIs associated with the canvas element; PixiJS is built on top of those and provides what's called a scene graph; in the realm of computer graphics scene graphs impose a treelike structure for organizing and rendering content (kinda oversimplifying but just go with it). Yes, the DOM has treelike structures too, but just because PixiJS and the DOM share a common abstraction does not make them the same thing.

 

To further complicate matters, there are dedicated Graphics Processing Units(GPUs) - great for high-end graphics performance. To get all that GPU goodness you use the Canvas API to get a webgl context like so:
 

gl = canvas.getContext("webgl") 

Once you do that you enter a different realm altogether. Now you're issuing commands directly to hardware...serious low-level $#!%. That ain't got nothing to do with the DOM either...nada, zilch. 

 

I get the feeling that you're coming from a front-end development background and you are still in the process of making the leap to game development. Your struggles stem from trying to frame or fit PixiJS into that context as if it were a DOM manipulation tool like JQuery. That's the wrong way to go about it. The challenge for you is to break from that mindset and to see it for what it really is - a graphics framework.

 

 

Link to comment
Share on other sites

>Yes, the DOM has treelike structures too, but just because PixiJS and the DOM share a common abstraction does not make them the same thing.

It doesn't really matter. The question is what will be faster - changing Pixi object or create new one.

xerver said the changing is faster, so then virtual dom is needed.

Link to comment
Share on other sites

>Yes, the DOM has treelike structures too, but just because PixiJS and the DOM share a common abstraction does not make them the same thing.

It doesn't really matter. The question is what will be faster - changing Pixi object or create new one.

xerver said the changing is faster, so then virtual dom is needed.

 

People don't use a virtual tree, and reuse and change objects constantly in PIXI. No virtual tree doesn't mean you have to recreate everything. Pixi is already a scene tree, the "virtual tree" already exists. Adding another on top doesn't make sense...

Link to comment
Share on other sites

No virtual tree doesn't mean you have to recreate everything. Pixi is already a scene tree, the "virtual tree" already exists. Adding another on top doesn't make sense

 

I think you don't understand how virtual dom works.

 

You create virtual dom

var vNode = h('container', h('text', {text="123"}))

then you create dom from it

var stage = createElement(vNode)renderer.render(stage)

then you create completely new virtual dom

var vNodeNew = h('container', h('text', {text="456"}))

then you create a diff between two virtual doms

diff = diff(vNode, vNodeNew);

and you apply this diff to the dom

 

patch(stage, diff)

var renderer.render(stage)

 

 

How does it suppose to work with pixi "virtual tree"?

 

Link to comment
Share on other sites

 

 

How does it suppose to work with pixi "virtual tree"?

 

 

It doesnt work like that with pixi, xerver already explained that working out which bits of a canvas have changed is more tricky (expensive) than working out which bits of a DOM structure have changed. For most pixi use-cases diffing and patching would slow down pixi i.e. it is simply faster to redraw an entire canvas, particularly so for games where much of the time all pixels change.

Link to comment
Share on other sites

I think you don't understand how virtual dom works.

 

I know exactly how virtual DOM works, and why it was created. Because creating, modifying, or in any way changing DOM is expensive. This is not true in pixi. Changing values of the tree in pixi has no performance impact, we recalculate the values everytime anyway. Preventing changes to position for example some frames because the diff says so results in exactly 0 optimization.

 

The differences in the cost of creating a DOM node and creating a js object are what virtual DOM is attractive. Creating js objects is way cheaper than creating or even modifying DOM nodes. Creating js object is not cheaper than modifying pixi's scene tree. Applying it here just means doubling the js object allocation already happening, resulting in no benefit.

 

This is the last I have to say on the topic, I recommend rereading what people have said because I think that you are misunderstanding how pixi works.

Link to comment
Share on other sites

>Because creating, modifying, or in any way changing DOM is expensive.

 

I think I understood what was wrong with this conversation. No, I am not talking about this aspect of virtual dom.

If you use FRP approach, it is much easier to recreate  the whole UI every change of the state instead of modifying UI directly.

So, I need to recreate the whole UI object model.

For example if I have timer, then render function always return new text object.

render time = h("text", {text: time})

and it is completely different from the common approach

var timeText = new PIXI.Text();changeUI time = timeText.text = time;

That is why there are two options

1) I can recreate the whole Pixi object model

2) I can recreate the whole virtual dom object model.

Virtual dom model is much lighter than Pixi model.

So it is preferable to work with virtual dom, compare two states of it, and apply diff to the real Pixi dom.

It isn't because I think changing the Pixi dom is expensive.

It's because I need to recreate the whole object tree after every change.

Is it clear now?

Link to comment
Share on other sites

>Because creating, modifying, or in any way changing DOM is expensive.

 

I think I understood what was wrong with this conversation. No, I am not talking about this aspect of virtual dom.

If you use FRP approach, it is much easier to recreate  the whole UI every change of the state instead of modifying UI directly.

So, I need to recreate the whole UI object model.

For example if I have timer, then render function always return new text object.

render time = h("text", {text: time})

and it is completely different from the common approach

var timeText = new PIXI.Text();changeUI time = timeText.text = time;

That is why there are two options

1) I can recreate the whole Pixi object model

2) I can recreate the whole virtual dom object model.

Virtual dom model is much lighter than Pixi model.

So it is preferable to work with virtual dom, compare two states of it, and apply diff to the real Pixi dom.

It isn't because I think changing the Pixi dom is expensive.

It's because I need to recreate the whole object tree after every change.

Is it clear now?

 

If you need to create the whole object tree every change, then you should rethink your methodology. Do what you feel is better for your application. I would look into and use object pooling.

Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...