When resizing an X3DOM element I'm currently facing the problem that the ratio of the displayed nodes is not correct (objects get streched or compressed).
Resizing is currently done via manipulation of the style attributes of the x3d dom node and the child canvas object as shown here:
http://www.x3dom.org/x3dom/test/functional/cssIntegration.html
This works well as long width & height both get increased about the same amount, but for my project I need to ensure that I can also just adjust width OR height.
Is there any way to make X3DOM correct the ratio?
Was able to solve this with the following method (though i do not know if this intended use):
Remove <scene> dom element from x3d element
Insert <scene> element at old position
This seems to fix this.
Related
I'm trying to understand animation loops in WebGl, along with React.
Basically, does the browser repaint specific elements without repainting the whole screen? Does a a reflow always refresh the whole screen? What exactly is the difference between what happens when you manually refresh the window with a refresh button, verses what reflow or repaint? I know this technology has been around awhile, but I never really dove into it much before.
I'm just trying to to understand how a webGL code animates on a canvas element and how React changes elements on a screen, without the whole screen reloading. I've read about requestAnimationFrame, and about how React bundles and diffs virtual dom changes, reducing the number of requests for rerender, but my question is more about the entire window reloading, verses rerendering individual components only. Im building a site with gatsby/react and babylonjs, and just trying to wrap my head around the underlying concepts. Thanks.
What the browser does is somewhat undefined. You give it HTML elements, it somehow draws them on the screen. How it optimizes that process is undefined, all that's defined is what the results are kind of supposed to be like. I say "kind of" because even a simple element like <p>Hello world</p> will be rendered differently on different browsers and differently on the same browser on different OSes or in the same browser on the same OS but with different OS settings etc..
In general the browser builds a tree of nodes (the elements and their contents) called the DOM. It then walks that tree and builds whatever it needs to apply the CSS and then render those elements. Most browsers would try to cache data at various points in that process so that if something changes on the page they don't have to compute everything from scratch. Example might include they generate a glyph (The pixel for a letter), store those pixels somewhere, next time they need to draw the letter at the same size they can just use the pixels they already generated instead having to rasterize that letter from the font definition.
does the browser repaint specific elements without repainting the whole screen?
That's up to the browser.
Does a a reflow always refresh the whole screen?
That's up to the browser. If the browser has way to figure out it only has to compute a partial reflow of some branch of the tree then it might not have to refresh the whole screen.
What exactly is the difference between what happens when you manually refresh the window with a refresh button, verses what reflow or repaint?
Refreshing a window is like killing a program and re-running it from scratch. All the data has to be reloaded either from the network or from the cache, the text gets parsed into elements, etc..
Reflow is computing where all the elements belong, where words or elements wrap, what size they are.
Repaint is drawing the elements. You can repaint without reflow.
how a webGL code animates on a canvas element
A canvas is just a rectangle of pixels, similar to an <img>. The difference is you can get one of several APIs to affect those pixels ("2d", "webgl", "webgl2", "webgpu", ...)
When you change those pixels the browser knows that <canvas> element needs to be re-drawn. How it re-draws it is up to the browser but at does have to at least follow the rules of the spec so for example a <canvas> like pretty much all elements, has CSS applied (it could have border, a background image/color/pattern, rounded corners, etc....). Elements are composited on top of each other so you might have elements in front of the canvas, you might have elements behind the canvas.
Like I said above, what the browser does to draw the elements is undefined but you can certainly imagine that if it can figure out the only thing that changed is the canvas's content, and there are no elements in front of the canvas, and there is nothing behind the canvas, and the canvas is opaque, then it could, potentially, just re-draw the canvas area only.
That situation is rare though. For example, most three.js examples have text at the top positioned over the canvas (the title of the example). Many also have an FPS meter. Some have a drop down UI. All of that is drawn over the canvas so at a minimum, the new contents of the canvas have to be drawn into the window and then those other elements have to rendered on top of that.
Again, how that, happens is up to the browser. It could use software rendering to draw those elements pixel by pixel, or it's possible it has stored the contents of those elements in textures and draws them as quads on top using the GPU.
how React changes elements on a screen, without the whole screen reloading
I'm not sure what you mean by reloading. React keeps its own "virtual DOM". It then tries to apply the changes in the virtual DOM to the actual browser DOM. If there are no changes needed to some elements those elements will not be affected.
From the POV of the browser, nothing is different. All the browser sees is the DOM. If you make changes to the DOM (using React or anything else), then, once your current event exits, the browser will schedule a task to walk the DOM and re-draw the page (using optimizations to re-compute/re-draw less is up to the browser).
I'm using the SpanLabel Component, but on the screen the text content does not occupying the full width when text size is lower
Someone can help please?
This can happen if the width isn't deterministic. The SpanLabel won't be able to reflow and at best will cause only its own Container to resize. There are two solutions:
Deterministic hierarchy - this is generally best but not always possible
Use TextArea - sometimes this works around the issue by reducing the hierarchy depth.
Deterministic layout means that the size of the elements is determined in a clear way by the hierarchy. E.g. BoxLayout.Y is deterministic on the X axis as it gives the components on the X axis all available space. FlowLayout isn't deterministic as it gives components their preferred size.
Some layouts can go back and forth and vary in determinism based on their axis.
This is important because when we layout the components we go from top down. So we go through the Form to its children asking each for their preferred size. If at this point the SpanLabel doesn't know its size it can give the wrong value and we can't really fix that later as we don't reflow the UI. Reflow would create a potential infinite loop and a performance problem at best.
We try to workaround some of this behavior by making a revalidate() call within TextArea but that has its limits. If the hierarchy is too deep the preferred size is already set and won't adapt. SpanLabel is just a Container with a TextArea and a Label (for the icon). So by only using a TextArea you'd slightly simplify the hierarchy and it sometimes might be enough. E.g.
TextArea t = new TextArea(myText);
t.setEditable(false);
t.setFocusable(false);
t.setUIID("Label");
What is the best way to manage a very large amount of images (10,000+) in WPF? This is for a 2d tile map editor similar to this : http://www.mapeditor.org/ .
At the moment i have a canvas with all tiles as an image and a list box which contains the different images to choose from. Each tile is added to the canvas as children and then stored in a list for later access. You paint into the canvas by setting the Source property of a tile to the one selected in the listbox. It works well with around 50x50 tile maps but anything above that causes loading delays, in general slow application.
Any suggestions on this? Would QT maybe be more suited instead of wpf?
Thanks in advance
Check out Implementing virtualized panel series of articles.
Virtualized panels are efficient, because:
Only the displayed elements (and a few extra around the borders to enable smooth scrolling) are in the memory (and rendered).
Elements are reused, instead of being repeatedly created and discarded - an old cell is simply filled with new content (supplied with new DataContext) and used in new location.
You might also try to use WPF's DataGrid for this, it supports virtualization out of the box and is essentially what are you trying to do.
WPF is certainly able to do this, if implemented properly (if you can do that in JavaScript, you can certainly do it in WPF as well).
So I realize that I am venturing outside of the intended use of a Canvas here and will likely have to come up with a more manual solution. However, not being overly experienced in WPF I was hoping that there may be some solution which would allow me to continue using a Canvas control and the features it gives you for free.
The issue revolves around a Canvas which is used to zoom in and out of an image and some number of child controls that belong to the Canvas. These child controls are to be placed at various positions on the image and, as such, the Canvas works nicely in that it handles all of the layout/positioning for me as I zoom in or out.
However, one drawback is that the Canvas scales these child controls up as I zoom into the image, causing them to become too large to be usable in practice. What I am looking for is a solution that allows me to zoom into an image that belongs to a canvas without also zooming up the size of the child controls, preferably handling the layout for me.
I have tried modifying the width and height of these child controls as the zoom factor increases or decreases, but there is a slight lag time and it all looks a bit 'jerky'.
If it comes down to it I will simply do all of the zooming/panning/layout myself, but I thought I would ask first just to make sure that I am not missing anything that would allow me to tell the Canvas to not scale the size of certain controls. Thanks in advance.
You can bind the children's RenderTransform to the inverse of the Canvas' transform, see my answer to this similar question on rotation.
This is more of a thought than an answer, but what if you set a transform on the element that you did not want scaled that was the opposite of the canvas itself. So for example, if the canvas had a scale transform of 2.0, set the element to have a scale transform of 0.5. You could probably accomplish this by binding the transform values together using a value converter.
You'll probably want to make sure the element has a render transform origin of 0.5,0.5 so that it scales from the center.
I have a control that has a list that varies in length greatly. This control appears in various places meaning that i cannot calculate its position and desired height easily.
Moreover all I want is for the scrollviewer to simply size itself according to its parent. currently it insists on sizing itself according to the content.
currently when i have a list that exceeds the height of the screen the whole control extends off the bottom and the scrollviewer shows no bar (because it has stretched to the heigth of the contents and so thinks it is not required).
I've not included code as the object graph is fairly deep.
What i am looking for is a set of conditions that would cause the scrollviewer to resize itself according to its content rather than its parent.
I have it working in a similar situation involving grids and datagrids, the unique part of this control is that there is a list containing controls.
Any ideas? I would prefer solutions that don't require use of code behind - but im really not in a position to be choosey.
Here are common reasons that come to mind that would allow a scroll viewer to size to its contents rather than to its "parent":-
It's placed on a Canvas or a StackPanel
It's assigned to a Grid row/column with it's Horizontal or Vertical alignment not set to Stretch and its content size is less than the size of the row or column.
Its ultimately upto the containing panel how it chooses to size a child element so its not really possible to dictate this completely from code inside the child.