excaliburjs / Excalibur

🎮 Your friendly TypeScript 2D game engine for the web 🗡️

Home Page:https://excaliburjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Font.measureText() returns a weird BoundingBox

levx-me opened this issue · comments

commented

Steps to Reproduce

I tried to use a background image and a text for ScreenElement so I did something like:

                let background: GraphicsLayer
                if (!layers.has("background")) {
                    background = layers.create({ name: "background", order: -1 })
                } else {
                    background = layers.get("background")
                }
                background.use(myBackgroundImage.toSprite())

                this.graphics.use(new Text("Press Start"))

The text is written on top of the (0, 0) coordinate, taking up a space of negative top and negative left values.
I investigated the reason and I figured out that Font.measureText() returns a weird BoundingBox of negative top and left values.

Expected Result

Font.measureText() should return a BoundingBox of left=0, top=0 value so that the image can be properly overwrapped with the text

Actual Result

Font.measureText() returns a BoundingBox of negative left and top values so that the text and image don't overwrap

Environment

  • browsers and versions: Google Chrome Version 117.0.5938.149 (Official Build) (arm64)
  • operating system: Mac Sonoma
  • Excalibur versions: 0.28.1

Current Workaround

I couldn't find a workaround yet

commented

FYI, it still happens even though I create an additional layer for the text with order >0

commented

Also, the reason why Font.measureText() matters is, it is called in this line when calculating the localBounds of Text

commented

This was solved by setting font.baseAlign = BaseAlign.Top

@levx-me I'll double check the code to make sure everything makes sense. Let me know if you run into anything weird with text and fonts.

The excalibur Font.measureText() will delegate the HTML Canvas measureText when not a SpriteFont, which will definitely produce negative local bounds on text. I believe this is the result of different character layouts/kerning/alignment/dangling parts of glyphs. The built in canvas draws text from the bottom left (roughly) which is completely different to all the other drawing APIs, making it very confusing.

commented

I think the default baseAlign needs to be changed to 'Top' which is intuitive for most frontend/game devs

@levx-me Totally agree, I'll make a new issue to that effect #2799