Best Fit #114
Replies: 6 comments 11 replies
-
Hi, thank you for your interest in three-mesh-ui and your wish to contribute ! This feature is actually on the roadmap, tracked here: #27 @GoncaloBastos three-mesh-ui generally tries to mimic HTML/CSS API, so for what you call Content Size Fitter we should just add an I don't know if your implementation is right or not, would you mind filing a PR with an example so we can try an actual implementation please ? |
Beta Was this translation helpful? Give feedback.
-
Hey all, just wanted to share some tought on "Best Fit" proposal @GoncaloBastos nice features, and great preview implementation. @GoncaloBastos and @felixmariotto in the preview implementation we can notice the following variables : maxFont and upscaling single property new ThreeMeshUI.Text({
fontSize: 0.55,
fitFont: true,
minFontSize: 0.45,
maxFontSize: 0.65,
}); we could have new ThreeMeshUI.Text({
fontSize: 0.55,
fitFont: [0.45,0.65] // or {min:0.45,max:0.65} it would be better at the end of this post
}); relative new ThreeMeshUI.Text({
fontSize: 0.55,
fitFont: ["-19%","16%"] // this doesn't look nice, but at least it is relative
}); Now if a user change the container size and text fontSize, the fit would stay relative. No needs to also update fitFont property (theorically) And if we could try to improve reading by using factors instead of string percentage new ThreeMeshUI.Text({
fontSize: 0.55,
fitFont: [-0.19,0.16] // this might be confusing system unit between 0.55,-0.19,0.16
}); we could rename the at the end new ThreeMeshUI.Text({
fontSize: 0.55,
fitFontFactor: 0.19 // the fontSize of 0.55, can be reduce by maximum of 0.55*0.19
}); |
Beta Was this translation helpful? Give feedback.
-
I'm going to open a PR as @felixmariotto asked, but in the meantime there are a couple of things I would like to continue discussing. Namely: multiple inlines with bestFit clashing attributes width:auto |
Beta Was this translation helpful? Give feedback.
-
@GoncaloBastos I'm beginning to think that we will have less design issues if it's the parent that is responsible for bestFit. This way the user set bestFit on the parent and we can easily check for clash with |
Beta Was this translation helpful? Give feedback.
-
Consider this HTML/CSS fiddle. The red div is always So basically I think that in three-mesh-ui, when the layoutUpdate cascades through the component hierarchy and encounters a component with
This way when doing 2), InlineManager knows the maximum line width and break lines when necessary (or when mandatory if no maximum line width). If the content must overflow the maximum dimensions, it should overflow in priority from the bottom like what we can see in HTML/CSS, see fiddle. In my opinion this feature is not trivial to implement, it should be done in a separate PR from bestFit. |
Beta Was this translation helpful? Give feedback.
-
I have a couple of questions regarding enable/disable behaviorWhen we set However, when setting it to false (after it being true), should the What updates should we trigger when setting this attribute? parsing and layout I'm guessing? However, when we are disabling it and if keeping the current fontSize, then we can skip both parsing and layout. In case "bestFit" :
if ( this.isBlock && options[ prop ] == true ) {
parsingNeedsUpdate = true;
layoutNeedsUpdate = true;
}
this[ prop ] = options[ prop ];
break; If we do want to store the original when to calculate fontSizeThis calculation needs to happen before In this case we would also need to call parseParams would look like this in Block: parseParams() {
if ( this.bestFit ) {
// We only need to run this logic if at least one child is a Text object.
if ( this.children.find( child => child.isText ) ){
this.calculateBestFit();
}
}
} I still need to figure out the best place for the actual best fit algorithm. The current implementation needs to compute the following information for each text child: Most of this is already implemented one way or another inside border radiushaving rounded borders reduces both the usable width and height of the block. Should we take that into account in our calculations or let the user just set an appropriate padding value? |
Beta Was this translation helpful? Give feedback.
-
Hi there!
I've been trying to implement a couple of features on top of the existing code base and I would like to open the implementations up for debate in case it's something we might want to include in Three Mesh UI directly.
The two features I have in mind are adaptations from existing functionality in Unity:
Best Fit
: Adjust Font Size so that text fits inside a given Block, within a min/max range).ContentSizeFitter
: Adjust a Block's height/width (I think in this case we can only really adjust the height with this) based on Text font size and length.For the Content Size Fitter logic, I calculate the inline values, followed by calculating the lines and finally getting the total height for the given inline component and apply said height to the parent Block. Most of the logic is just recycled from the Text, TextManager and InlineManager.
Best Fit is implemented similarly, where most of the logic is just adopted from existing code. I essentially calculate the text height for a given font size and iterate until the text height fits within its parent block.
This is the iterative method:
I've also decoupled the calculation of inlines from the component's fontSize, passing the fontSize directly instead. Likewise for the lines calculation, I pass it an inlines array instead of relying on the variable in the component. Finally, the height calculation takes an array of line objects. This decoupling allows me to calculate text height without having to actually set the value in the component.
I'd love to get some feedback regarding the above method. Is there a way to optimize this further? I went with a minimization problem approach as I couldn't figure out a way to calculate the correct font size for a given width/height directly.
To give a bit more context regarding why I need these two features:
Best Fit: Some of our text is driven by a backend, meaning we can't ensure that it will always fit into a fixed size block. In this case, we would like for the text font size to be adjusted so that it still fits said block.
Content Size Fitter: In a separate instance, also regarding backend driven text, we want to list a number of items with a title and a description. The length of both the title and the description can vary widely and we want the description to appear/disappear when clicking the title. The description would appear right under the title, pushing the remaining titles further down the block. In order for the remaining items to be pushed down, we need to set the height of the description block so it matches its content height.
EDIT
Moved
fit-content
discussion to #119Beta Was this translation helpful? Give feedback.
All reactions