So, the other day I needed to add a background color to a TextField in Flash. I don’t mean a rectangular area of color such as the backgroundColor property of a TextField would produce, but irregularly sized rectangles that varied by the width of each line of text in the dynamic TextField. Basically, I needed to be able to set the css background-color property of the TextField. Now admittedly, it’s been some time since I’ve messed with css in Flash, so I was hoping that background-color was now supported. A quick peek at the docs, though, said that wasn’t the case. Of course I tried it anyway – you never know if you may just turn up an undocumented little feature. Of course, there was no joy. My next thought was perhaps by playing with the setSelection() method and alwaysShowSelection property of the TextField, I could somehow finesse a different colored background and text color, but it didn’t take too long to abandon that line of attack. Finally I said, nuts to all that, and just created a class that extends Sprite, but adds a TextField instance and uses TextLineMetrics to create blocks of color the width of each line of text. You can see it in action below (click on the stage to change the properties):
Basically, you use the class just like you would a TextField but the backgroundColor property will apply only to the areas of text – not to the entire rectangular field. The document class used to create the example looks like this:
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package { import com.onebyonedesign.utils.BackgroundTextfield; import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.AntiAliasType; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; /** * quick example of BackgroundTextfield class * @author Devon O. */ public class Main extends Sprite { private var _btf:BackgroundTextfield; public function Main():void { initTextfield(); stage.addEventListener(MouseEvent.CLICK, changeTextField); } private function initTextfield():void { _btf = new BackgroundTextfield(); _btf.width = 200; _btf.multiline = true; _btf.wordWrap = true; _btf.autoSize = TextFieldAutoSize.LEFT; _btf.antiAliasType = AntiAliasType.ADVANCED; _btf.backgroundColor = 0x000000; _btf.defaultTextFormat = new TextFormat(new VerdanaFont().fontName, 15, 0xFFFFFF); _btf.embedFonts = true; _btf.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas at leo eget nisl porta viverra. Ut laoreet, dui at tempus vestibulum, eros leo egestas neque, id adipiscing odio eros et lectus. Vivamus pretium lorem sit amet nulla. Praesent nec dolor at augue ultrices blandit. Quisque aliquet ultrices mi?"; _btf.x = 10; _btf.y = 10; addChild(_btf); } private function changeTextField(event:MouseEvent):void { stage.removeEventListener(MouseEvent.CLICK, changeTextField); _btf.backgroundColor = 0x00AA00; _btf.textColor = 0x990000; _btf.width = 450; _btf.htmlText = "Donec ac nibh. <font color='#000099'><u>Phasellus</u></font> sed sem sed mauris mattis laoreet. Ut fermentum augue ac pede. Duis vitae augue sed nulla lacinia tempor. Pellentesque non ante in magna tincidunt malesuada. Nunc eu mi. Nulla adipiscing posuere nunc. Donec congue, sem vitae aliquam sagittis, tellus lectus laoreet libero, in interdum mi dui ut tellus. Nam pulvinar nibh a ante. Maecenas laoreet placerat ante. Vivamus feugiat magna ut leo. Integer sed risus. Quisque porttitor massa a sem."; _btf.embedFonts = false; _btf.setTextFormat(new TextFormat("_serif", 25)); } } } |
If interested, the entire BackgroundTextfield class is below. I didn’t include all properties/methods of the TextField class out of a combination of laziness and lack of personal need, but it isn’t too wildly difficult to add more to it if you really want to.
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
package com.onebyonedesign.utils { import flash.display.Sprite; import flash.events.Event; import flash.text.StyleSheet; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextLineMetrics; /** * TextField with CSS background-color like property * @author Devon O. */ public class BackgroundTextfield extends Sprite { private var _bg:Sprite = new Sprite(); private var _bgcolor:uint = 0xFFFFFF; private var _tf:TextField = new TextField(); private var _changed:Boolean = false; public function BackgroundTextfield():void { super(); addChild(_tf); addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); } public function set text(value:String):void { _tf.text = value; _changed = true; requestRedraw(); } public function get text():String { return _tf.text; } public function set htmlText(value:String):void { _tf.htmlText = value; _changed = true; requestRedraw(); } public function get htmlText():String { return _tf.htmlText; } public function set multiline(value:Boolean):void { _tf.multiline = value; } public function get multiline():Boolean { return _tf.multiline; } public function set wordWrap(value:Boolean):void { _tf.wordWrap = value; } public function get wordWrap():Boolean { return _tf.wordWrap; } public function set defaultTextFormat(value:TextFormat):void { _tf.defaultTextFormat = value; } public function get defaultTextFormat():TextFormat { return _tf.defaultTextFormat; } public function set embedFonts(value:Boolean):void { _tf.embedFonts = value; } public function get embedFonts():Boolean { return _tf.embedFonts; } public function set styleSheet(value:StyleSheet):void { _tf.styleSheet = value; _changed = true; requestRedraw(); } public function get styleSheet():StyleSheet { return _tf.styleSheet; } public function set selectable(value:Boolean):void { _tf.selectable = value; } public function get selectable():Boolean { return _tf.selectable; } public function set autoSize(value:String):void { _tf.autoSize = value; } public function get autoSize():String { return _tf.autoSize; } public function set backgroundColor(value:uint):void { _bgcolor = value; _changed = true; requestRedraw(); } public function get backgroundColor():uint { return _bgcolor; } public function set mouseWheelEnbabled(value:Boolean):void { _tf.mouseWheelEnabled = value; } public function get mouseWheelEnbabled():Boolean { return _tf.mouseWheelEnabled; } public function set antiAliasType(value:String):void { _tf.antiAliasType = value; } public function get antiAliasType():String { return _tf.antiAliasType; } public function get textHeight():Number { return _tf.textHeight; } public function get textWidth():Number { return _tf.textWidth; } public function get length():int { return _tf.length; } public function setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void { _tf.setTextFormat(format, beginIndex, endIndex); _changed = true; requestRedraw(); } public function set textColor(value:uint):void { _tf.textColor = value; } public function get textColor():uint { return _tf.textColor; } override public function set width(value:Number):void { _tf.width = value; _changed = true; requestRedraw(); } override public function get width():Number { return _tf.width; } override public function set height(value:Number):void { _tf.height = value; } override public function get height():Number { return _tf.height; } override public function set mouseEnabled(value:Boolean):void { super.mouseEnabled = value; _tf.mouseEnabled = value; } private function drawBackground():void { if (contains(_bg)) { removeChild(_bg); _bg = new Sprite(); } _bg.mouseChildren = false; _bg.mouseEnabled = false; var i:int = _tf.numLines; if (i > 0) { while (i--) { var met:TextLineMetrics = _tf.getLineMetrics(i); var lbg:Sprite = lineBackground(met.width, met.height); lbg.y = i * (lbg.height); lbg.x = met.x; _bg.addChild(lbg); } addChildAt(_bg, 0); } _changed = false; } private function lineBackground(w:Number, h:Number):Sprite { var s:Sprite = new Sprite(); s.graphics.beginFill(_bgcolor); s.graphics.drawRect(0, 0, w, h); s.graphics.endFill(); return s; } private function requestRedraw():void { if (stage) { stage.invalidate(); } } private function onAddedToStage(event:Event):void { removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); stage.addEventListener(Event.RENDER, onRender); if (_changed) { requestRedraw(); } } private function onRender(event:Event):void { if (_changed) { drawBackground(); } } private function onRemovedFromStage(event:Event):void { removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); stage.removeEventListener(Event.RENDER, onRender); } } } |
And in other news, I finally got a copy of “The Essential Guide to Flash CS4 AIR Development” – the book I technically reviewed. I know it’s kind of silly, but I just love seeing my name and picture in print. Now, I just need to write a book rather than just read one. Any topic suggestions?
Well, for a start, let me tell you that I learn a lot from you, especially about AS3 – from especially your tutorial “Creating Simple Website in AS3”.
You have passion and generosity, and your writing style is really modest and not pretentious. You like avoiding using jargon that sickening me so someone can be called a programmer/coder.
I have plenty of AS3 books include the most talk about – Moock, but I will certainly buy any book written by you. Almost certainly, if I have enough money, you are my first choice, if I have to hire you to build a lot of my flash project.
And finally, to answer your question : You should elaborate and write “Creating simple website in AS3.” into one comprehensive book.
Hey Beebs, Thank you for taking the time to write such a long and kind comment. I really appreciate the feedback. That idea is actually something my wife and I were discussing. If I do sit down and take the time to write a book, that is most likely exactly the topic I’d tackle. Thank you again. d.
Hey Devon.
If you and your wife will certainly tackle that topic I really support you. In the market now, most of AS3 books always talk from bottom to up : starting the definition of variable and end with Array. And then the discussion/application of those. But honestly, it’s quite rarely in day to day business, we talked about what so called multidimensional Array, for example. So the thorough discussion over any jargon should be minimized. We always can use “Moock” book if we really want to go deep and discuss like a geek over any jargon.
I think your book should use approach up to bottom. You know, the way “Creating simple AS3 website” is written. Starting from one single objective and idea and then dissected directly within it’s chapter, OR better, creating different section to discuss particular jargon.
And Devon, please please (my wish-list), use only 1 tight single project to illustrate the point. My experiences in the past reading many books out there, that using too many different examples, is just annoying.
Cheers
Heya,
I have stumbled upon this website through Google, so I’m afraid that means I’m a bit of a newbie when it comes to.. well pretty much everything you write about.
I have this website http://www.bcmh.co.uk/AAVA/ which I have built using AS2 however I was hoping to apply a yellow ‘highlight’ background effect to the text (imported from an external .txt file). I am curious is this solution applicable to my problem?
I have not worked with Components or Classes extensively so I apologise for my ignorance. However as this was my last site built in AS2 (personal pledge) I am looking to move towards working with a heavier emphasis on the coding, have you any advice on sites/books to start with.
Many Thanks
Hey Luke,
Unfortunately this little trick relies on TextLineMetrics which is only available in AS3/Flash Player 9 (and higher). As far as learning AS3 goes, I found this book a bit simplistic, but a lot of people love it: http://oreilly.com/catalog/9780596527877/index.html Maybe it could help you out…
Hi,
couldn’t comment in the relevant entry.
Is it ok if I use a slightly modified version of OBOTooltip in a piece of work I’m doing (to a tight deadline)?
I may change things further, or write my own. But if it owes anything to yours I’ll put the attribution atthe top (though that gets lost in the SWF, doesn’t it?)
cheers (+ great blog!),
Henry
Hi Henry,
I usually ask for credit if at all possible, but yes, you are welcome to use it. Post a link to the finished project if you can.
Thanks for the comments on the blog..
d.
Sure will do. Come to think of it, there will be a credit’s/front page too.
I curerntly get an empty tip – no text – and I wonder if it’s the LibraryFont/ArialFont class that’s in your examples, haven’t done this before myself. (I’m way behind you on AS). So my LibraryFont/ArialFont constructor doesn’t do anything much.
However when I add a line to the class like:
_format.font = Verdana;
or
_format = new TextFormat(“Verdana”,fontSize,fontColor);
This doesn’t seem to make any difference either, anything obviously wrong?
In my example, LibraryFont is a font contained within the .fla library and set to export for actionscript with the linkage/class name “LibraryFont”.
Thank your for your class, it saves me a lot of time!
It works perfectly!