Jump to content

inputText dynamic resize


gexzor
 Share

Recommended Posts

So I am trying to create an input field above a sphere. I have problems with applying the proper proportions of the input field without the text either being way too small, or being stretched and smudged if when it get large enough. Furthermore I have problems with the textPlane, on which the input is attached, getting in the way and preventing hover and mouse events on the sphere below it.

Here is what I got at line 203: http://www.babylonjs-playground.com/#28AM9V#24

I feel like I'm lacking proper control of positioning and sizing the input, probably because I'm doing something silly somewhere. Would love to get some ideas from you guys on how to fix it :)

Link to comment
Share on other sites

I don't think you're doing anything silly.  It's a bit of a paradigm shift from traditional UI to getting everything working in 3d.  One thing I did was ensure my plane did not collide with any other meshes and was facing the camera, but that is only part of the solution (depending on your "viewpoint").  If you want the entire text input always visible that could be difficult depending on position and perspective of camera.

Here is a way I got the plane not blocked by meshes (I move it up until it's not colliding with a sphere) - maybe that is part of a solution - certainly there are more elegant solutions that keep the plane always visible, when possible.  In my game I went a bit above the sphere, so I could see it better from below (camera position.y lower):
https://www.babylonjs-playground.com/#Q81PBV#2

Also, if you want to know how wide your input text would be, you can measure at different font sizes and adjust accordingly.  Not a full solution - I know from a mobile device that it is cumbersome.  You could use something like this to adjust font or plane size perhaps.  The important call is "measureText":

var planeTexture = new BABYLON.DynamicTexture('planeTexture', 512, scene, true);
planeTexture.hasAlpha = true;

let textureContext: CanvasRenderingContext2D = planeTexture.getContext();
textureContext.font = 'bold 300px verdana';
let size = planeTexture.getSize();
textureContext.save();
textureContext.fillStyle = hexColour;
textureContext.fillRect(0, 0, size.width, size.height);
let textSize = textureContext.measureText(letter); // doesn't measure height!

// textSize.width has text width with that font.

 

Link to comment
Share on other sites

So I have messed around a bit more and I'm now rid of the problem with the textPlane blocking the mouse events. I however still have problems with getting the input field to resize along with the length of the input string. autoStretchWidth doesn't seem to do anything for me unfortunately. Manually setting width or height immediately gives me problems with the font stretching and smudging :/

Line 203: http://www.babylonjs-playground.com/#28AM9V#25

Link to comment
Share on other sites

Hi @gexzor 
input.autoStretchWidth = true; should do the trick, but it seems to stop working after the initial render.. really odd.
Temp-fix;

input.autoStretchWidth = true;
input.processKeyboard = function (evt) {
    this.processKey(evt.keyCode, evt.key);
    this.autoStretchWidth = true;
};

And here's your PG in action, note that the inputText has px size limitations, so to avoid the scaling breaking, i normalized your numbers a bit and made the plane mesh bigger to offset for it, results in some hard to see pixelation, but you can set it as you like ofcourse.

http://www.babylonjs-playground.com/#28AM9V#29

Edit;
Found the issue aswell; the width function resets autoStretchWidth to false.

Object.defineProperty(InputText.prototype, "width", {
                get: function () {
                    return this._width.toString(this._host);
                },
                set: function (value) {
                    if (this._width.toString(this._host) === value) {
                        return;
                    }
                    if (this._width.fromString(value)) {
                        this._markAsDirty();
                    }
                    this.autoStretchWidth = false;
                },
                enumerable: true,
                configurable: true
            });

 

Link to comment
Share on other sites

33 minutes ago, aWeirdo said:

And here's your PG in action, note that the inputText has px size limitations, so to avoid the scaling breaking, i normalized your numbers a bit and made the plane mesh bigger to offset for it, results in some hard to see pixelation, but you can set it as you like ofcourse.

http://www.babylonjs-playground.com/#28AM9V#29

Thanks a lot man. The autoStretch fix fixes that part of the problem perfectly :)

The pixelation is kinda rough when zooming in on a sphere though. The problem with the textPlane blocking mouse events is also an issue for me :/

Link to comment
Share on other sites

  • 4 months later...

Hi @Deltakosh, Do you know a way to have one textarea? 

I saw you can have one with castorGUI library, but my input need to be on a plane or mesh.


Plus I think the inputText is kind of poor in term of user interaction, no shortcut, can't copy/paste, no text selection. Do you think I could maybe have access to the code in order to improve it? I have looked at the code here and I think some things are doable : https://github.com/BabylonJS/Babylon.js/blob/master/gui/src/controls/inputText.ts

Cheerz, Pichou

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...