Skip to content

Instantly share code, notes, and snippets.

@davestewart
Last active December 21, 2015 05:48
Show Gist options
  • Save davestewart/6259113 to your computer and use it in GitHub Desktop.
Save davestewart/6259113 to your computer and use it in GitHub Desktop.
package text
{
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* Class to manage a TextField instance and reduce its fontsize to ensure it stays within its original dimensions
* @author Dave Stewart
*/
public class TextFieldController
{
// ---------------------------------------------------------------------------------------------------------------------
// { region: variables
// properties
protected var tf :TextField;
protected var maxHeight :int;
protected var format :TextFormat;
protected var size :Number;
protected var prop :String;
// ---------------------------------------------------------------------------------------------------------------------
// { region: instantiation
public static function create(tf:TextField):TextFieldController
{
return new TextFieldController(tf);
}
public function TextFieldController(tf:TextField)
{
this.tf = tf;
initialize();
}
protected function initialize():void
{
tf.addEventListener(Event.CHANGE, onTextFieldChange);
tf.wordWrap = true;
maxHeight = tf.height;
format = tf.getTextFormat();
size = Number(format.size);
// gets over a bug with rotated textfields
prop = tf.rotation > 45 ? 'width' : 'height';
}
// ---------------------------------------------------------------------------------------------------------------------
// { region: accessors
public function set text(value:String):void
{
tf.text = value.replace(/(^\s*|\s*$)/g, '');
fit();
}
// ---------------------------------------------------------------------------------------------------------------------
// { region: protected methods
protected function fit():void
{
tf.autoSize = flash.text.TextFieldAutoSize.LEFT;
size = int(format.size);
tf.setTextFormat(format);
if(tf[prop] >= maxHeight && size > 5)
{
size --;
format.size = size;
fit();
}
}
// ---------------------------------------------------------------------------------------------------------------------
// { region: handlers
protected function onTextFieldChange(event:Event):void
{
fit();
}
// ---------------------------------------------------------------------------------------------------------------------
// { region: utilities
}
}
@davestewart
Copy link
Author

Actually, thinking about making this class more useful, a static implementation that monitored multiple textfields, either using internal lists, or an array of TextFieldController instances would be a neater solution:

TextFieldController.create(tf);

Have added that...

@ThomasBurleson
Copy link

Here is the styling I often use:

package text 
{
  import flash.events.Event;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;
  import flash.text.TextFormat;

  /**
   * TextFieldController 
   *
   * Class to manage a TextField instance and reduce its fontsize to ensure 
   * it stays within its original dimensions/bounds
   *
   * @author Dave Stewart
   * @blog   http://www.davestewart.co.uk
   *
   * @date   August, 2013
   *
   */
  public class TextFieldController
  {

    // **************************************************
    // Public Static Methods
    // **************************************************

    public static function create(tf:TextField):TextFieldController
    {
      return new TextFieldController(tf);
    }

    // **************************************************
    // Public Properties
    // **************************************************

    /**
     * Mutator for the textField's `text` property
     * Force clears all prepending and trailing spaces
     */
    public function set text(value:String):void
    {
      tf.text  = value.replace(/(^\s*|\s*$)/g, '');
      fit();
    }


    // **************************************************
    // Constructor
    // **************************************************

    public function TextFieldController(tf:TextField) 
    {
      this.tf = tf;
      initialize();
    }


    // **************************************************
    // Protected Methods
    // **************************************************

    /**
    * Attach change handler to watch for text changes 
    */
    protected function initialize():void 
    {
      if ( !tf ) return;

      tf.addEventListener(Event.CHANGE, onTextFieldChange);
      tf.wordWrap   = true;

      maxHeight     = tf.height;
      format        = tf.getTextFormat();
      size          = Number(format.size);

      // gets over a bug with rotated textfields
      prop          = (tf.rotation > 45) ? 'width' : 'height';

    }

    /**
     * Recursively auto-change the fontsize until
     * the resulting total text width fits the TextField bounds
     */
    protected function fit():void
    {
      tf.autoSize = flash.text.TextFieldAutoSize.LEFT;
      size    = int(format.size);
      tf.setTextFormat(format);

      if(tf[prop] >= maxHeight && size > 5)
      {
        size --;
        format.size = size;
        fit();
      }
    }

    // **************************************************
    // Protected EventHandlers
    // **************************************************


    /**
     * Auto-resize font when the text content changes
     */
    protected function onTextFieldChange(event:Event):void
    {
      fit();
    }


    // **************************************************
    // Protected Properties
    // **************************************************

    protected var tf        :TextField;
    protected var maxHeight :int;
    protected var format    :TextFormat;
    protected var size      :Number;

    protected var prop      :String;


  }

}

@ThomasBurleson
Copy link

Also I think you have a potential bug:

You cache the maxHeight but do not account for rotation; which may require you to catch the maxWidth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment