Centering TextField inside a Sprite

Hello everyone!

I want to center a TextField inside a Sprite object but I have some problems because it seems that the local coordinates of the Sprite start at the lower right corner. So if I set the TextField coordinates to be the x and y coordinates of the Sprite, the TextField is positioned in the lower right corner of the Sprite.

Here is an image of what happens:

I want the TextField to be both horizontally and vertically centered inside the Sprite, but with these weird coordinates I can’t figure out how to do it.
So any help is appreciated! Thank you!

This is the code I use to create the Sprite and the TextField:

class Circle extends Sprite {
    public var number: TextField;

    public function new(size: Float) {
        super();

        drawCircle(size);
        drawNumber(size);
    }

    private function drawCircle(size: Float): Void {
        graphics.beginFill(0xd2e1ff);
        graphics.drawCircle(0, 0, size / 2);
        graphics.endFill();
    }

    private function drawNumber(size: Float): Void {
        var format: TextFormat = new TextFormat();
        format.font = "fonts/Sen-Regular.ttf";
        format.size = Std.int(size);
        format.color = 0xffffff;
        format.align = TextFormatAlign.CENTER;

        number = new TextField();
        number.text = (Math.random() < 0.50) ? "0" : "1";
        number.defaultTextFormat = format;
        number.selectable = false;
        number.width = width;
        number.height = number.textHeight;
        number.x = x;
        number.y = y;

        addChild(number);
    }
}

I think this might work:

class Circle extends Sprite {
    public var number: TextField;

    public function new(size: Float) {
        super();

        drawCircle(size);
        drawNumber(size);
    }

    private function drawCircle(size: Float): Void {
        graphics.beginFill(0xd2e1ff);
        graphics.drawCircle(size / 2, size / 2, size / 2);
        graphics.endFill();
    }

    private function drawNumber(size: Float): Void {
        var format: TextFormat = new TextFormat();
        format.font = "fonts/Sen-Regular.ttf";
        format.size = Std.int(size);
        format.color = 0xffffff;
        format.align = TextFormatAlign.CENTER;

        number = new TextField();
        number.text = (Math.random() < 0.50) ? "0" : "1";
        number.defaultTextFormat = format;
        number.selectable = false;
        number.width = number.textWidth + 4;
        number.height = number.textHeight + 4;
        number.x = (size - number.width) / 2;
        number.y = (size - number.height) / 2;

        addChild(number);
    }
}

When you drawCircle at (0, 0), it makes the center of your circle at the origin (0, 0) point. This is the first thing that probably was confusing here. Using size / 2 as the (x, y) point makes it behave more similarly to what you want, I think :smile:

To set a TextField to its exact text size, use the textWidth and textHeight values, plus 4. TextField has 2 pixels of margin on each side, so width = textWidth + 4 is right.

To center it, we can do x = (totalWidth - width) / 2, so in this case, the size value is our total width, and the textfield width is our width. Similarly for height. Try it out, and see how it works :slight_smile:

1 Like

Thank you so much! It’s working!

1 Like

Actually would not be exactly centered vertically due to the fact number.textHeight would not return the height of the number but the height of the font used (== font size): [TextField] How i get char bound (height of the number is smaller than the one of the font as all numbers are drawn above the font baseline).
So if you realy want to center it you should use something like:
number.y = (size - number.getLineMetrics(0).ascent) / 2 - 2;
But even that would not be perfect as numbers usually do not reach the font top line so their height is actually a bit smaller than what returned by ascent…