bryik/aframe-bmfont-text-component

[Feature Request] Vertical align text?

Closed this issue · 4 comments

It would be really nice to have the ability to vertical align text in the same way horizontal align works. Thanks!

bryik commented

There is another bmfont-text component currently in the process of being merged into A-Frame core which I believe contains all layout options available. If it can't do what you want, you'd probably need to look at modifying three-bmfont or layout-bmfont-text.

At first time i patch the code to let me center a text vertically, from it's original position. I really don't have to much time to test it and make it modular to send a PR but could be ok if you need to develop a hotfix:

//the metrics for this text layout
	  this._width = maxLineWidth
	  this._height = height
	  this._descender = lineHeight - baseline
	  this._baseline = baseline
	  this._xHeight = getXHeight(font)
	  this._capHeight = getCapHeight(font)
	  this._lineHeight = lineHeight
	  this._ascender = lineHeight - descender - this._xHeight

	  //layout each glyph
	  var self = this
		lines.forEach(function(line, lineIndex) {
	    var start = line.start
	    var end = line.end
	    var lineWidth = line.width
	    var lastGlyph

	    //for each glyph in that line first calculate...
	    for (var i=start; i<end; i++) {
	      var id = text.charCodeAt(i)
	      var glyph = self.getGlyph(font, id)
	      if (glyph) {
	        if (lastGlyph)
	          x += getKerning(font, lastGlyph.id, glyph.id)

	        var tx = x
	        if (align === ALIGN_CENTER)
	          tx += (maxLineWidth-lineWidth)/2
	        else if (align === ALIGN_RIGHT)
	          tx += (maxLineWidth-lineWidth)

	        //move pen forward
	        x += glyph.xadvance + letterSpacing
	        lastGlyph = glyph
	      }
	    }

	    //next line down
	    y += lineHeight
	    x = 0
	  })

		var fullBlockCenterVertical = opt.height/2
		var textCenterVertical = y/2
		var yText = fullBlockCenterVertical - textCenterVertical
		//i have my height calculated, so i push glyphs into the center of the image
		lines.forEach(function(line, lineIndex) {
	    var start = line.start
	    var end = line.end
	    var lineWidth = line.width
	    var lastGlyph

	    //for each glyph in that line...
	    for (var i=start; i<end; i++) {
	      var id = text.charCodeAt(i)
	      var glyph = self.getGlyph(font, id)
	      if (glyph) {
	        if (lastGlyph)
	          x += getKerning(font, lastGlyph.id, glyph.id)

	        var tx = x
	        if (align === ALIGN_CENTER)
	          tx += (maxLineWidth-lineWidth)/2
	        else if (align === ALIGN_RIGHT)
	          tx += (maxLineWidth-lineWidth)

	        glyphs.push({
	          position: [tx, yText],
	          data: glyph,
	          index: i,
	          line: lineIndex
	        })

	        //move pen forward
	        x += glyph.xadvance + letterSpacing
	        lastGlyph = glyph
	      }
	    }

	    //next line down
	    yText += lineHeight
	    x = 0
	  })

The main idea is to simulate a text rendering and calculate the the full dimensions before you make the render itself. After you can could calculate your vertical position offset a priori.

bryik commented

Closing as this issue has been open for quite some time and I'm about to archive this project.

Not sure, but the baseline property of <a-text> may provide the vertical alignment you were looking for.