AS3 TextLineMetrics 在对象位于显示列表上之前获取文本宽度

发布于 2024-12-28 20:49:21 字数 249 浏览 0 评论 0原文

我有一个库 MovieClip 类,它仅由包含在 MovieClip 中的动态文本字段组成。

我想实例化此 MC,用文本填充文本字段,获取结果文本的宽度,如果宽度小于预定义的 MIN_WIDTH 值,则附加更多文本。

当宽度等于或大于我的 MIN_WIDTH 值时,将此 MovieClip 类添加到显示列表中。

我的问题是,有谁知道在将文本字段添加到显示列表之前是否可以使用 Textlinemetrics 检索文本字段中的文本长度?

I have a library MovieClip Class that consists solely of a dynamic textfield contained in a MovieClip.

I want to instantiate this MC, populate the textField with text, get the width of the resulting text and, if the width is less than a predefined MIN_WIDTH value, append more text.

When the width is equal to or greater than my MIN_WIDTH value, add this MovieClip class to the display list.

My question is, does anyone know if its possible to retrieve the length of text in a textField using Textlinemetrics BEFORE the textField has been added to the display list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦断已成空 2025-01-04 20:49:21

您缺少以下信息,因为当您创建和配置文本字段时,文本测量工作正常,而无需将其添加到显示列表中。

诀窍是确保在完全配置 TextField 后最后设置“文本”属性。考虑到所有先前配置的设置,设置“text”属性似乎最终确定了布局。

您遇到的问题可能是您正在设置“text”属性,然后更改其他设置,例如多行或嵌入字体。当您这样做时,getLineMetrics 将不会返回正确的值。如果您随后设置“text”属性并再次检查 getLineMetrics,则值将是正确的。请参阅此示例以及跟踪语句后面的注释。

var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf.embedFonts = true;
tf.text = "Hello"; //set text last
trace( tf.getLineMetrics(0).height ); //Traces 22.55 (correct)

var tf2:TextField = new TextField();
tf2.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf2.text = "Hello"; //set text first
tf2.embedFonts = true; //modify a property after setting text seems to make the TextField "dirty"
trace( tf2.getLineMetrics(0).height ); //Traces 1.15 (incorrect)

var tf3:TextField = new TextField();
tf3.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf3.text = "Hello";
tf3.embedFonts = true; //modifying a property after setting the text seems to make the TextField "dirty"
tf3.text = "Hello"; //setting the text again seems to fix the problem
trace( tf3.getLineMetrics(0).height ); //Traces 22.15 (correct)

这里的教训是配置 TextField 的顺序很重要。这被记录为正确的,例如,对于 defaultTextFormat 属性,您必须在设置文本之前设置该属性,否则您设置的新文本将不会采用 defaultTextFormat。在这种情况下,如果您打开了 embedFonts 并且它使用其他未嵌入的默认字体,则文本可能根本不会显示。因此,请确保首先设置 defaultTextFormat,配置其他属性,最后设置“text”,就在调用 getLineMetrics 之前。

在这里,使用我创建的这个函数。它强制您首先配置 TextField 的重要属性(文本、类型、多行、可选择、嵌入字体),然后后面的参数与 TextFormat 构造函数的参数完全相同,顺序相同。它确保您的属性以正确的顺序设置,文本最后分配,并且它将把您的 TextField 创建减少到一条语句:

public static function CreateTextField( text:String = "", type:String = null, multiline:Boolean = false, selectable:Boolean = true, embedFonts:Boolean = false, font:String=null, size:Object=null, color:Object=null, bold:Object=null, italic:Object=null, underline:Object=null, url:String=null, target:String=null, align:String=null, leftMargin:Object=null, rightMargin:Object=null, indent:Object=null, leading:Object=null ):TextField
{
    var tf:TextField = new TextField();
    tf.defaultTextFormat = new TextFormat( font, size, color, bold, italic, underline, url, target, align, leftMargin, rightMargin, indent, leading );
    tf.embedFonts = embedFonts;
    tf.multiline = multiline;
    tf.selectable = selectable;
    tf.type = type;
    tf.text = text; //setting text last ensures the text line metrics returns correct values
    return tf;
}

You are missing the following information, because text measurements work fine when you create and configure a text field, without ever adding it to the display list.

The trick is to make sure you set the "text" property LAST, after fully configuring the TextField. Setting the "text" property seems to finalize the layout, given all the previously configured settings.

The problem you're encountering is probably that you're setting the "text" property and then making changes to other settings such as multiline or embedFonts. When you do that, getLineMetrics will not return correct values. If you then set the "text" property and check getLineMetrics again, the values will be correct. See this example and the comments after the trace statements.

var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf.embedFonts = true;
tf.text = "Hello"; //set text last
trace( tf.getLineMetrics(0).height ); //Traces 22.55 (correct)

var tf2:TextField = new TextField();
tf2.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf2.text = "Hello"; //set text first
tf2.embedFonts = true; //modify a property after setting text seems to make the TextField "dirty"
trace( tf2.getLineMetrics(0).height ); //Traces 1.15 (incorrect)

var tf3:TextField = new TextField();
tf3.defaultTextFormat = new TextFormat( "Arial Black", 16, 0, false );
tf3.text = "Hello";
tf3.embedFonts = true; //modifying a property after setting the text seems to make the TextField "dirty"
tf3.text = "Hello"; //setting the text again seems to fix the problem
trace( tf3.getLineMetrics(0).height ); //Traces 22.15 (correct)

The lesson here is that the order you configure the TextField matters. This is documented to be true, for example, with the defaultTextFormat property, which you must set BEFORE setting the text, otherwise the new text you set will not pick up the defaultTextFormat. In that case, the text may not show up at all if you have embedFonts turned on and it uses some other default font that's not embedded. So make sure you set the defaultTextFormat first, configure other properties, and set the "text" last, just before you call getLineMetrics.

Here, use this function I created. It forces you to configure the important properties of the TextField first (text, type, multiline, selectable, embedFonts), and then the later parameters are exactly that of the TextFormat constructor, in the same order. It ensures your properties are set in the correct order, the text is assigned last, and it will reduce your TextField creation down to one statement:

public static function CreateTextField( text:String = "", type:String = null, multiline:Boolean = false, selectable:Boolean = true, embedFonts:Boolean = false, font:String=null, size:Object=null, color:Object=null, bold:Object=null, italic:Object=null, underline:Object=null, url:String=null, target:String=null, align:String=null, leftMargin:Object=null, rightMargin:Object=null, indent:Object=null, leading:Object=null ):TextField
{
    var tf:TextField = new TextField();
    tf.defaultTextFormat = new TextFormat( font, size, color, bold, italic, underline, url, target, align, leftMargin, rightMargin, indent, leading );
    tf.embedFonts = embedFonts;
    tf.multiline = multiline;
    tf.selectable = selectable;
    tf.type = type;
    tf.text = text; //setting text last ensures the text line metrics returns correct values
    return tf;
}
望笑 2025-01-04 20:49:21

当然 - 据我所知,无论文本字段是否在显示列表上,TextLineMetrics 都会起作用。您是否尝试过此操作但无法正常工作?如果是这样,请让我们知道您的代码 - 除非我遗漏了一些它应该可以工作的东西。

Sure - as far as I know, TextLineMetrics works regardless of whether a textfield is on the display list. Have you tried this and had trouble getting it to work? If so please let us know your code - unless I'm missing something it should just work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文