Entries Tagged as ''

Dynamically resizing text in Flash to fit a container

Earlier this year I ran into an interesting problem. I was generating images of thought bubbles randomly appearing in a Flash movie containing people’s messages they’ve entered in a web form. It was a nice interactive display. The trouble was that people inevitably would write thoughts of varying lengths, and either the short ones looked swamped by the bubble, or the long one’s over ran:

Bubbles overlapping

So, how could I determine the length and adjust the text size appropriately? After spending sometime attempting to use a variety of formulas I thought of a different approach: Firstly, start with the text size extremely large, say size 50. Then, check if it breaks the boundary of the bubble, if it does, drop the size by 2 points. Now does it break the boundary? If it does, drop the size… and so on until the text fits.

The result is neat thought bubbles with well sized text populating them:

Bubbles neatly sized

I’ve stripped the Actionscript 2 code out of my application by means of example, though it won’t run out of the box:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//Generate a bubble
function generateBubble() {
	//Duplicate the bubble dummy
	bubbleDummy.duplicateMovieClip ("bubble" + intDepth, getNextHighestDepth());
	//And select it
	objBubble = get("bubble" + intDepth);
 
	//Substitute in the response as dynamic text
	objBubble.txtResponse.text 	= loadResponseObj["response"+intResponse];
 
	//Set up the TextFormat
	myTextFormat = new TextFormat();
	myTextFormat.font = "my font";
	myTextFormat.size = 50;
 
	objBubble.txtResponse.embedFonts = true;
 
	//Autosize the dynamic text field
	objBubble.txtResponse.setTextFormat(myTextFormat);
	objBubble.txtResponse.autoSize = "left";
 
	while ( objBubble.txtResponse._height > 140 ) { 	// the text field is taller than the bubble
		myTextFormat.size -= 2; 			// shrink the font size by 2
		objBubble.txtResponse.setTextFormat(myTextFormat);
		objBubble.txtResponse.autoSize = "left";	// and resize the box...
	}
 
	//Set the backing the same height as the text field
	objBubble.backing._height = objBubble.txtResponse._height + 40;
 
	//Keep our records tidy
	intResponse ++;
	intDepth ++;
}

Obviously this solution is an iterative loop, so I’d like to hear if there are more elegant solutions.