Monday, March 09, 2009

AS3 Dynamic Text Wrapping or Flowing Around Objects

EDIT: Take a look here if you are able to use Flash Player 10. (http://labs.adobe.com/technologies/textlayout/)

The Flash community is still waiting for Adobe to implement dynamic or intelligent text wrapping into Flash. So meanwhile several programmers are creating their own solutions and work arounds.

After thinking about the problem, I did a quick search and I found that dispatchEvent.org actually had released a solution very similar to my own inital approach. So I took a look at their code and made some improves upon based off of their original dynamic text wrapping utility.

The improvements allow text to flow around multiple objects on the left and the right. It still utilizes BitmapData and transparent pixels around each slice, but simply manages a linked list of TextFormats to control the leftMargin. In addition, it will also accept a flash.geom.Rectangle as a bounding box to work in; the motivation for this function is to reduce the computational load.

Simply input a list of DisplayObjects for the $leftList and the $rightList. Here's the function prototype:
public static function bound($field:TextField, $leftList:Array, $rightList:Array, $wrapArea:Rectangle=null, $padding:Number=10):void;

To utilize it you would make an example call:
TextWrap.bound(tf,[o3,o4],[o1,o2]);

Where tf is the TextField which wraps around objects on its left o3 and o4 and warps around objects on its right o1 and o2.




Here is the code.

Of course, it's not perfect, but it's a starting point.

14 comments:

JRM said...

Wow! good job.
Funny I have been worrying about how to allow cms managed text to intelligently format around display objetcs recently for a project... you have certainly stopped me from worrying and got me excited to use.
THANKS!

Anonymous said...

Really good job.

I want to know that instead of DisplayObject if I would like to give path of image & can I take textarea instead of text field.

Pls help me.

Anonymous said...

Hi Henry,

Can you please help me out in implementing this in my example?

As sample application of this post.

Henry Tseng said...

I'm not sure if I understand completely what you're requesting, but Bitmap should inherit from DisplayObject so that you will be able to just simply add it to the list.

Henry Tseng said...

Here is an example implementation here.

Anonymous said...

Hi Henry,
How to use your TextWrap for wrapping a text filed inside a sprite? (as text displayed in a box)
Appreciated.
Hoang

Henry Tseng said...

Hoang, not sure where the issue you're running into might be. It should still work if your TextField is located in a Sprite. Could you show code?

Gary said...

Hi Henry,

I have a similar problem. I am using Flex Builder. I want my component to display a text box. In which you have text wrap arround images. There are two ways to do it, One is using mx:TextField HtmlText = "" /; the other way is using AS. my AS component extend BOX or Canvus, I have to add the Visual Component in to display. but your function has no return. Advice please. Gary

Anonymous said...

Is there a way for this to work using htmlText. I've found the word wraping works with html however, the html i.e. hyperlinks are deactivated....?

any ideas?

thanks

Greg

Henry Tseng said...

This work around uses the method "getCharIndexAtPoint". Using htmlText introduces issues where the character locations are not accurate. I'm afraid right now this breaks the calculations.

Anonymous said...

That's exactly what i'd thought you'd say, i've had this problem in the past and have come up against it again....I guess i need to get CS4 adn use the TextLayout Framework.

Thanks for repying anyway

Greg

Anonymous said...

this doesn't work at all for me, I keep getting

ArgumentError: Error #2015: Invalid BitmapData.

Don Booth said...

Henry,

I want to thank you for your TextLayout class.

For the life of me I have not been able to find Adobe's TextLayout Framework. But for most things (at least for most of what I'm doing) your class is simple and to the point.

Thanks,

Anonymous said...

ON line 187 you have :
for(; charIndex>0 && !text.charAt(charIndex).match(_whiteSpace); charIndex--);

I am getting an error with the first ;

Seems like an odd loop, you are missing a beginning declaration I guess.