David Freire
David Freire

Reputation: 671

EASELJS - underline text

I haven't seen any native support for this in the framework, so i did some code, by measuring the font Height and drawing a line underneath. I need to find out how much Descent the font has, as getMeasureHeight only measures until the font baseline.

I have the following code, so far:

var textLayer = new createjs.Text();
var fontSizeInPx = Math.round((self.fontSize() / 72) * 300, 0) + "px";

textLayer.textBaseline = 'bottom';
textLayer.text = text;
textLayer.font = getFontStyle(self.isBold(), self.isItalic(), fontSizeInPx, 'Arial');;
var textMeasures = textLayer.getBounds();

var underlineShape = new createjs.Shape();

var startYCoords = self.positionY() + textMeasures.height;

underlineShape.graphics.beginStroke(self.color()).setStrokeStyle(2)
    .moveTo(self.positionX(), startYCoords)
    .lineTo(textMeasures.width + self.positionX(), startYCoords);

And this is the result:

enter image description here

How can i get this metric?

Thanks

Upvotes: 1

Views: 1187

Answers (2)

David Freire
David Freire

Reputation: 671

I was able to find a solution here, for getting the font metrics: https://stackoverflow.com/a/9847841/3202740

Having the font descent, the only thing that has to be done is getting the font Height and adding the font descent:

var lineBreaks = self.canvasLayer.text.split("\n");

$.each(lineBreaks, function (idx, text) {
    if (text != '') {
        var textLayer = new createjs.Text();
        var fontSizeInPx = Math.round((self.fontSize() / 72) * 300, 0) + "px";

        textLayer.textBaseline = 'bottom';
        textLayer.text = text;
        textLayer.font = getFontStyle(self.isBold(), self.isItalic(), fontSizeInPx, 'Arial');;
        var textMeasures = textLayer.getBounds();
        var textMetrics = getTextHeight('Arial');

        var underlineShape = new createjs.Shape();

        var startYCoords = self.positionY() + (textMeasures.height * (idx+1));

        underlineShape.graphics.beginStroke(self.color()).setStrokeStyle(2)
            .moveTo(self.positionX(), startYCoords + textMetrics.descent)
            .lineTo(textMeasures.width + self.positionX(), startYCoords + textMetrics.descent);

        underlineShapes.push(underlineShape);

        self.canvasLayer.stage.addChild(underlineShape);
    }
});    

Resulting in:

enter image description here

Upvotes: 1

gskinner
gskinner

Reputation: 2488

The easiest way to do this is to take advantage of the textBaseline property. Setting it to alphabetic instead of top (the default) will draw your text with the font baseline at y=0. You can then grab the width with getMeasuredWidth(), and draw the line at the x & y of the Text object (possibly offsetting the y by a pixel or two to put it where you want).

Here's an example: http://jsfiddle.net/gskinner/y919oszd/

It's also worth noting that other baseline values, like "ideographic" are very unreliable, and behave differently on different browsers. The most reliable is "alphabetic", followed by "top", which is rendered incorrectly by FireFox: https://bugzilla.mozilla.org/show_bug.cgi?id=737852.

Upvotes: 2

Related Questions