AS3 + HTML Text +
tags
Posted: December 19, 2007 at 1:46 pm I discovered a few things when trying to add img tags to html content on a site I have been working on. Mabye this is common knowledge, but I thought I'd share my experience since I had a hard time getting anymore info on it.
-
Nesting an <a href> tag around an <img> tag doesn't work.
- When you embed an image into text using the img tag the image is added to the TextField's DisplayList. For example if you embed an image in the TextField "contentfield", it's the same as doing contentfield.addChild(htmlImage); Which brings me to…
- The TextField has a method called getImageReference(id:String):DisplayObject; Basically this method returns the DisplayObject or image that is contained within a given TextField. This is great, but I noticed it only works when there is one image in a TextField. If someone can confirm this, that would be great.
Basically I wanted to link the embedded images in my TextField so the popup a larger version of the image. Simple enough, yet when I wrapped the img tag with an href, the outside of the image would show the hand cursor, but the image wouldn't link. Now if the parent of the img is the TextField, then wouldn't it make sense to have numChildren as a TextField Method? Then I could loop through the children of the text field and create buttons. I've made this request to Adobe, and so far they have been receptive to the idea. Hopefully this will get passed through.
I did however, come up with another way to dynamically load images into a TextField. When loading a swf into a TextField using the img tag you can set the instance name of that swf using the id attribute. I use this id attribute to pass the path to the image, as well as an image id that is passed into the popup window that loads the larger image. Here's an example of the html source that is passed into the TextField.
<img src="thumb.swf" id="../flashassets/images/slideshow/2_sm.jpg,2_sm.jpg" />
I separate the two parameters using a comma which are String split in the thumb.swf. Here's the code in the thumb.swf:
if(this.parent.name != null) var results:Array = this.parent.name.split(","); var imagepath:String = (this.parent.name == null) ? "../flashassets/images/slideshow/1_sm.jpg" : results[0]; var link:String = (this.parent.name == null) ? "http://www.google.com" : results[1]; var image:Sprite = new Sprite(); image.useHandCursor = image.buttonMode = image.mouseEnabled = true; image.addEventListener(MouseEvent.CLICK, onClick); this.addChild(image); var loader:Loader = new Loader(); var request:URLRequest = new URLRequest(imagepath); loader.load(request); image.addChild(loader); var border:Sprite = new Sprite(); this.addChild(border); border.graphics.lineStyle(2, 0xCC3300, 1, true, "none"); border.graphics.drawRect(1,1,148, 148); function onClick(event:MouseEvent):void{ navigateToURL(new URLRequest("javascript:window.open('image.php?cat=slideshow&id="+link+"','atest','menubar=yes,resizable=no,width=710,height=730,left=50,top=50');"), "_self"); }
The Discussion
see what everyone is saying
very cool. interesting solution. i'll try it out:)
adobe should just get on the ball, eh?
hey, thank you very much, smerter solution, naja this issue was a nightmare for me :\
GREAT!
thx!
I've come up with a decent workaround. Hope this helps someone.
What you do is put a MouseEvent.CLICK listener on the TextField then you check to see if the mouse clicked within the rectangle area of the embedded image.
//t is the TextField
//emb is the embedded image
t.addEventListener(MouseEvent.CLICK, onTextClick);
emb = t.textField.getImageReference("icon") as Loader;
function onTextClick(e:MouseEvent):void
{
var p:Point = new Point(e.localX, e.localY);
var r:Rectangle = btnRuleBook.getRect(e.target as TextField);
if (r.containsPoint(p))
{
//launch URL or whatever
}
}
woops sorry. btnRuleBook is supposed to be emb.
You're absolutely right. one should be able to enumerate children of the TextField if they are in fact children of the TextField. I recently ran across an implementation where being able to index images referenced in img tags in that manner would have saved a lot of time. I ended up using regex to list all img tags… not ideal really.
here's the regex to match all img tags
var reImages:RegExp = //sigm;
var oIMGMatches:Object = reImages.exec(sContent);
[...] Note: (April 2, 2009) You cannot nest an <img> tag within an <a> tag. [Ref] [...]
I have two images (thumbnails, really) that I embed right into the textfield like this: giving the next one an id ="2″.
I then attach event listeners to them like this:
i = 1;
while (displayBox.getImageReference(i.toString()) != null) {
displayBox.getImageReference(i.toString()).addEventListener(MouseEvent.MOUSE_DOWN, displayImage);
i++;
}
That works fine for me and allows me to bring up full size images. My problem is that as soon as I alter htmlText even a TINY bit (eg htmlText += ".") the formatting goes all over the shop. Stumped.
Sorry if that didn't make sense. Stupid wordpress is knocking out my angle brackets. My image tag looks like this: img src="thumbs/placeholder.jpg" id = "1″ hspace = "0″ vspace = "0″/
I ended up just adding a MouseEvent.CLICK listener to the textfield and then checking if the target was an [object Loader] in order to figure out if I was clicking an image. I could then query the contentLoaderInfo in order to retrieve a URL and grab the big image.
It looks like a lot of these problems stem from the fact that TextField is, as you might suspect from the name, just for displaying text. Adobe have obviously bodged some sort of vague html support into it but it remains a bodge. For instance: tags create a Loader instance, attach it to the TextField and pass it a URL – but as TextField doesn't inherit from DisplayObjectContainer it shouldn't be able to do that. You also don't get any of the DisplayObjectContainer methods, so while you can reference the Loader object that's a child of textField, you can't remove it with textField.removeChild or loader.parent.removeChild. TextFields can't do that. I'll use AIR next time.
You can reference more than one image from the html using the getImageReference(id:String). You just have to give the different different id names in the html, then you reference them separately by that id name.
<img id="dragImage" ….
<img id="mainImage" ….
then use getImageReference("dragImage") and getImageReference("mainImage") etc.
The reason why the images get fucked up is because of the fontsize. It's very silly but if you put the fontsize to zero then the images are clickable. It's ok for me 'cause I just needed an easy way to get those thumbs displayed while keeping my html untouched. Works like a charm if you just need images in that textfield.
You can change the fontsize per tag with CSS, maybe someone needs to give that one a try. Sounds like it could work. We'll then have a perfectly good way to get those tag wrapped images to display in textfields.
I ment tag wrapped images to display in textfields, ofcourse… silly wordpress