問題
予めタイムラインに置いたTLFテキスト(TLFTextField)インスタンスに、TextLayoutFormatオブジェクトでフォーマットを適用しようとしても反映されないという問題です。TextLayoutFormatインスタンスをTextFlow.hostFormatあるいはTextFlow.formatプロパティに代入しても、TLFTextFieldインスタンスのフォーマットが変わりません。
たとえば、メインタイムラインにTLFテキストを置いて、my_txtというインスタンス名をつけます(図001)。そのフレームアクションとして以下のスクリプト001を書きます。
図001■メインタイムラインにTLFテキストのインスタンスmy_txtを置く
TextLayoutFormatインスタンスにTextLayoutFormat.colorプロパティを設定したうえで、TLFTextFieldインスタンスのTLFTextField.textFlowプロパティからTextFlowオブジェクトを参照し、そのFlowElement.formatプロパティに代入しています。なお、TLFTextFieldインスタンスの基本的な扱い方については、gihyo.jp連載「ActionScript 3.0で始めるオブジェクト指向スクリプティング」の第39回「TLFTextFieldクラスを使う」またはAdobeデベロッパーセンター「ActionScript 3.0でFlash Professional CS5のText Layout Frameworkを使う」をお読みください。
スクリプト001■タイムラインのTLFTextFieldインスタンスにTextLayoutFormatオブジェクトを設定
// フレームアクション: メインタイムライン
// TLFTextFieldインスタンスmy_txtを配置
import fl.text.TLFTextField;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.TextLayoutFormat;
var my_txt:TLFTextField;
var myTextFlow:TextFlow = my_txt.textFlow;
var my_fmt:TextLayoutFormat = new TextLayoutFormat();
my_txt.text = "test";
my_fmt.color = 0xFF0000;
myTextFlow.format = my_fmt;
myTextFlow.flowComposer.updateAllControllers();
|
[ムービープレビュー]を確かめると、テキストのカラーは変わりません(図002)。TextLayoutFormatオブジェクトをTextFlow.hostFormatプロパティに設定しても同じ結果です。
図002■TextLayoutFormatオブジェクトのカラーの設定がテキストに適用されない
原因
FlowElement.formatやTextFlow.hostFormatプロパティに設定したTextLayoutFormatインスタンスのフォーマットより、[プロパティ]インスペクタの設定が勝るためです。TLFTextField.tlfMarkupプロパティを用いると、TLFTextFieldインスタンスのテキスト設定が「Text Layout Framework Markup」形式でXMLデータの文字列として得られます。
たとえば、[プロパティ]インスペクタの設定が前掲図001の場合には、つぎのtrace()関数により、XMLデータが以下のように[出力]されます(改行を加えて見やすくしました)。[プロパティ]インスペクタの設定は、<span>要素に加えられていることがわかります。
// フレームアクションに追加
trace(my_txt.tlfMarkup);
|
<TextFlow color="#ff0000" whiteSpaceCollapse="preserve" xmlns="http://ns.adobe.com/textLayout/2008">
<p direction="ltr" paragraphEndIndent="0" paragraphSpaceAfter="0" paragraphSpaceBefore="0" paragraphStartIndent="0" textAlign="start" textAlignLast="start" textIndent="0" textJustify="interWord">
<span color="#000000" fontFamily="_ゴシック" fontLookup="device" fontSize="12" fontStyle="normal" fontWeight="normal" kerning="auto" lineHeight="120%" textAlpha="1" textRotation="auto" trackingRight="0%">
test
</span>
</p>
</TextFlow>
対処法
フォーマットを動的に適用する必要があるかどうか、どれほど細かい設定をするかによって、やり方は変わります。
[1] [プロパティ]インスペクタでフォーマットを設定する
フォーマットを動的に適用しなくてよいなら、[プロパティ]インスペクタですべて設定するのが簡単です。操作できる項目の数も多いので、細かな設定ができます。
[2] TLFTextFieldクラスのプロパティでフォーマットを設定する
TextLayoutFormatでなく、TLFTextFieldクラスにもフォーマットを操作するプロパティがあります。たとえば、前掲スクリプト001のテキストのカラーなら、TLFTextField.textColorプロパティで設定できます(図003)。ただし、フォーマットに使えるプロパティの種類は多くありません。
図003■TLFTextField.textColorプロパティでテキストのカラーを設定する
[3] TLFTextField.setTextFormat()メソッドを使う
TLFTextField.setTextFormat()メソッドを使うと、TextFieldクラスと同じTextFormatオブジェクトでフォーマットが適用できます(スクリプト002)。ただし、このメソッドはすでにあるテキストにフォーマットを適用します。つまり、TLFTextField.textプロパティにテキストを設定したあとに呼出さなければなりません。TextFieldインスタンスとは異なり、これから加えられるテキストに対するdefaultTextFormatプロパティはありません[*1]。
スクリプト002■タイムラインのTLFTextFieldインスタンスにTextFormatオブジェクトを設定
// フレームアクション: メインタイムライン
import fl.text.TLFTextField;
var my_txt:TLFTextField;
var my_fmt:TextFormat = new TextFormat();
my_fmt.color = 0xFF0000;
my_txt.text = "test";
my_txt.setTextFormat(my_fmt); // 設定されたテキストに適用
|
[4] TLFTextFieldインスタンスを動的につくる
TextLayoutFormatオブジェクトのフォーマットを動的に適用したいときは、TLFTextFieldインスタンスも動的につくれば、フォーマットは基本的にデフォルト(親)にしたがいます(スクリプト003)。そのため、FlowElement.formatやTextFlow.hostFormatプロパティに代入したTextLayoutFormatオブジェクトのフォーマットが適用されます。
スクリプト003■動的に生成したTLFTextFieldインスタンスにTextLayoutFormatオブジェクトを設定
// フレームアクション: メインタイムライン
import fl.text.TLFTextField;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.TextLayoutFormat;
var my_txt:TLFTextField = new TLFTextField();
var myTextFlow:TextFlow = my_txt.textFlow;
var my_fmt:TextLayoutFormat = new TextLayoutFormat();
addChild(my_txt);
my_txt.text = "test";
my_fmt.color = 0xFF0000;
myTextFlow.format = my_fmt;
myTextFlow.flowComposer.updateAllControllers();
|
[5] 取出したSpanElementインスタンスにTextLayoutFormatオブジェクトを設定
<span>要素を取出すこともできないではありません。エレメントはSpanElementインスタンスになります。FlowGroupElement.getChildAt()メソッドでTextFlowインスタンスから順に子のエレメント(FlowElementオブジェクト)を取出します。そのうえで、SpanElementインスタンスのFlowElement.formatプロパティに、TextLayoutFormatオブジェクトを設定します(スクリプト004)。
スクリプト004■取出したSpanElementインスタンスにTextLayoutFormatオブジェクトを設定
// フレームアクション: メインタイムライン
// TLFTextFieldインスタンスmy_txtを配置
import fl.text.TLFTextField;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.elements.ParagraphElement;
import flashx.textLayout.elements.SpanElement;
import flashx.textLayout.formats.TextLayoutFormat;
var my_txt:TLFTextField;
var myTextFlow:TextFlow = my_txt.textFlow;
var paragraph:ParagraphElement = myTextFlow.getChildAt(0) as ParagraphElement;
var span:SpanElement = paragraph.getChildAt(0) as SpanElement;
var my_fmt:TextLayoutFormat = new TextLayoutFormat();
my_txt.text = "test";
my_fmt.color = 0xFF0000;
span.format = my_fmt;
myTextFlow.flowComposer.updateAllControllers();
|
[6] Text Layout Framework Markup形式のXMLデータを使う
テキストに細かな設定を加えたいときには、Text Layout Framework Markup形式のXMLデータが使えないか検討してみるとよいでしょう。gihyo.jp連載「ActionScript 3.0で始めるオブジェクト指向スクリプティング」の第40回「Text Layout Frameworkでテキストコンテンツを表示する」およびAdobeデベロッパーセンター「ActionScript 3.0でFlash Professional CS5のText Layout Frameworkを使う」に解説しましたので、それらをご参照ください。
[*1] [ヘルプ]の[TLFTextField]で「TLFTextField.setTextFormat()メソッド」の項を見ると、「新しいテキスト用のデフォルトフォーマットを設定するには、defaultTextFormatを使用します」と説明されています。しかし、TLFTextFieldクラスには同名のプロパティが掲載されていません。プロパティを参照するとTextFormatオブジェクトが返されるものの、設定しても効果はありません。[ヘルプ]の記載の誤りと受取るべきでしょう。
|
作成者: 野中文雄
作成日: 2010年12月26日