Automatic font size adjuster

First I have to say sorry to all the not ‘actionscript-geeks’, but I have another script I want to share. I made a TextField behaviour that might come in handy for other people too.. I made a short video to show how it works.

It is called AutomaticFontSizeBehaviour AutomaticFonSizeBehavior :)

package  
{
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
 
	/**
	 *  @author Jankees.van.Woezik
	 */
	public class AutomaticFonSizeBehavior 
	{
 
		private var _textField:TextField;
		private var _startSize:Number;
		private var _currentSize:Number;
		private var _prevText:String;
		private var _maxHeight:Number;
		private var _minimalFontSize:uint;
 
		/**
		 * Usage:
		 * 
		 * _updater = new AutomaticFonSizeBehavior(textField);
		 * 
		 * // this is enough for input fields, if you set text using code you should call the update function after you have set the text like this:
		 * 
		 * _updater.update();
		 * 
		 */
		public function AutomaticFonSizeBehavior(inTextField:TextField,inStartSize:Number = 40,inMinimalFontSize:uint = 9, willUpdateOnInput = true) 
		{
			_minimalFontSize = inMinimalFontSize;
			_startSize = inStartSize;
			_currentSize = inStartSize;
			_textField = inTextField;
			_prevText = "";
 
			_maxHeight = _textField.height;
 
			_textField.addEventListener(Event.REMOVED_FROM_STAGE,dispose);
 
			if(willUpdateOnInput) addEventListeners();
 
			setFontSize(_startSize);
 
			update();
		}
 
		public function update(event:Event = null):void 
		{
			_textField.scrollV = 0;
 
			if(_prevText.length > _textField.length)
                setFontSize(_startSize);
 
			while (_maxHeight < _textField.textHeight + (4 * _textField.numLines)) 
			{ 
				if(_currentSize <= _minimalFontSize) break;
				setFontSize(_currentSize - 0.5);
			}
 
			if(_currentSize <= _minimalFontSize) 
			{
				_textField.text = _prevText;
			} 
			else 
			{
				_prevText = _textField.text;
			}
		}
 
		private function addEventListeners():void 
		{
			_textField.addEventListener(Event.CHANGE,update);
			_textField.addEventListener(KeyboardEvent.KEY_UP,update);
		}
 
		private function setFontSize(inSize:Number):void 
		{
			_currentSize = inSize;
 
			var currentTextFormat:TextFormat = _textField.getTextFormat();
			currentTextFormat.size = _currentSize;
 
			_textField.setTextFormat(currentTextFormat);
			_textField.defaultTextFormat = currentTextFormat;
		}
 
		/**
		 * Dispose everything
		 */
		private function dispose(event:Event):void 
		{
			_textField.removeEventListener(KeyboardEvent.KEY_UP,update);
			_textField.removeEventListener(Event.CHANGE,update);
			_textField.removeEventListener(Event.REMOVED_FROM_STAGE,dispose);
 
			_textField = null;
		}
	}
}

update: Thanks to Thijs for the update! Copy & paste is now supported!
update: Thanks to Sandro Padin for the improvements!!


THE COMMENTS:



  • What erik said 2 hours later:

    Sweet, nicely designed class dude.

  • What jankees said 2 hours later:

    Thanks! The project '#endathetmespijt' will be launched next monday! I post a message when it is live!

  • What Thijs said 9 hours later:

    VET VET VET!!!!

    Really nice. I am definitely going to use this.

    But I didn't know TextFields dispatches KeyBoardEvents? I thought only the Stage does it. Maybe you should also listen to the flash.events.TextEvent.TEXT_INPUT event?

    Does it work when I do 'copy-paste'?

  • What Bernard said 11 hours later:

    @Thijs Textfields do dispatch Keyboard Events, this is done by the InteractiveObject class and it's the super of TextField.

    @JanKees Nice! Added the class to my repos ;)

    Like Thijs said it would be nice if it will work with 'copy-paste'. I tried it @ the demo you showed me yesterday and it didn't work.

  • What Jankees said 21 hours later:

    Thanks! Do you have any idea how to solve the copy paste thing? The only thing I can come up with is overwriting the setter 'text' in textfield, which is a bit dirty…?

  • What Thijs said 22 hours later:

    I fixed your copy-paste thing!!!

    Just add:

    _textField.addEventListener(TextEvent.TEXT_INPUT,update);

    And it will work!

  • What Jankees said 22 hours later:

    Thanks!

    Maybe it would be nice that an update woudn't be exucuted if there is no text change… it gets fired 3 times for every keystroke…

  • What Sandro said 55 days later:

    This looks great. One question though, how do you use it? Would you need some sort of global variable and do var tf: AutomaticFontSizeBehaviour = new AutomaticFontSizeBehaviour(myTextField); ?

    Thanks!

  • What Sandro said 55 days later:

    One other suggestion.. This class is great not just for input text, but for dynamic text that is only set once, like item titles or descriptions. I modified your constructor to add a willUpdate boolean property, then I only add the event listeners if the textfield is meant to be updated more than once.

    Sandro

  • What Jankees said 55 days later:

    @Sandro, Thanks for you feedback, if you send me your adjustments I will post it here.

    Best,

Leave a Reply