Floats

Floats are used when you have an image, and you would like the text to wrap around it. TLF 2.0 will include support for Floats. This feature is currently under development, so the final form may change, but what follows is a description of how it works now. We are very interested in feedback on this feature, so please let us know how it works for you, and if you have any suggestions for improvements.

“float” is a property that can be applied to an InlineGraphicElement that controls the placement of the graphic and the text around it. A value of “none” will cause the InlineGraphicElement to appear as an inline and be treated as a large character in the text. This is the behavior of the InlineGraphicElement as it was in TLF 1.0. The float can also be assigned the values “left”, “right”, “start” or “end”. A value of “left” will cause the graphic to appear at the left edge of the container, and the text will wrap around it. A value of “right” causes it to appear at the right edge of the container. “start” and “end” will resolve to either left or right depending on the direction property of the paragraph; a value of “ltr” causes start to be left and end to be right, while a value of “rtl” for direction does the reverse. An InlineGraphicElement is considered to be a float if its float value is not “none.”

A float will appear at the same level as the line it is on if it can while maintaining the anchor in the line. If putting the float at the same level as the line (and thus wrapping the line around the float) would cause the anchor to get pushed out of the line, then the float appears below the line.

If the float width exceeds the column width it places the float anyway, and the float may either bleed over other content or be clipped. If the float height exceeds the column height, the float is pushed to the next column or container. Note that in this description, width and height should be understood as logical width and logical height so that it works the same when the text is vertical (when blockProgression is “rl”). Likewise “left” in vertical text will align the float with the logical left edge (the top), and “right” in vertical text will align the float with the bottom edge.

You can control how close the text and the image are by setting the padding properties of the InlineGraphicElement. Setting the padding values causes the InlineGraphicElement to be treated as slightly larger (or smaller if the padding is negative) than its width and height would indicate. Setting the paddingLeft of a left float will cause the float to be indented from the edge, and setting the paddingTop causes it to get pushed down.

“clear” is a new paragraph-level property that controls the placement of paragraph elements relative to floats. A clear value of “left” will cause the element to be placed after any float that appears to the left, and a clear value of “right” causes the element to appear after any right float. A “clear” value of “both” causes the element to appear after all floats, either on the left or right. A clear value of “none” allows the text to appear next to the float, and this is the default. Clear does not apply at the sub-paragraph or span level. Note that in order to affect the placement of the element, the element must start at a location where there is a float.

If a container has floats and has vertical justification turned on, the vertical justification will be ignored.

A float will always appear in the same container as its anchor point. If there is not room for the anchor point, the anchor point and the float will be pushed to the next container.

Horizontal alignment is not applied to floats – it applies only to text. However, a right float will align to the right edge of measured text.

When a range of multiple characters is selected, and it includes a float, the float is highlighted. When the selection is a simple insertion point (0 length range), then the cursor will be positioned at the anchor point. When cursoring over an anchor point, there is a “stutter” where the cursor appears not to move, but is in fact stepping over the zero-length anchor. This allows precise positioning of the insertion point relative to the anchor.

When we are importing text using the TextConverter.TEXT_FIELD_HTML_FORMAT, the “align” attribute of an element is used to determine the “float” value of the corresponding InlineGraphicElement. A value of “left” or “right” will be passed through to the float property on the InlineGraphicElement, and otherwise the float property will be left as undefined and get the default value “none”. Note that while this approximates the behavior of the htmlText property of TextField, it is slightly different because the TextField will always place the float below the line, either to the left or right, whereas the TLF will attempt to place the float at the same level as the line if possible.

Here’s a markup example of a floating image:

<img float=”left” height=”50″ width=”19″ source=”myImage.png”>

Here’s the same one with some padding applied:

<img float=”left” height=”50″ width=”19″ source=”myImage.png” paddingRight=”5″>

31 Responses to Floats

  1. Pradeek says:

    Why not use the standard HTML tags for all the features in TLF. Dynamic rich text is unnecessarily complicated to implement in TLF.

  2. It’s great you’re continuing your work on TLF, though I still hope text selection will become built into flash player eventually.One comment about float=”none”.In TLF 1.1 when an image is inserted, the line becomes as high as if the image was a character with a height that usually exceeds the height of an image (closest size in pts?) and a blank space appears above image because of that. Is this behaviour is going to be addressed in TLF 2?

  3. would be very nice to have a component in Flex / Air, which was managing the text as the application of the NYT or read epub file type.

  4. Mr Monstre says:

    Hi,have you got an example of this utilisation of the “float” with a inlinegraphicelement ?thanks

  5. Robin Briggs says:

    Mostly we do use HTML syntax, but we don’t have a CSS engine available. So formatting properties end up getting affixed to the elements as properties in XML. The float implementation in TLF is very similar to how its done in CSS, but the float property is on the element instead of being applied with a rule.

  6. Robin Briggs says:

    Thanks for your interest!How images are considered for lineHeight hasn’t changed, but now you have more control over it. You should be able to affect the line height by setting a negative paddingTop on the image.

  7. Robin Briggs says:

    The InlineGraphicElement now has a “float” property which you can set directly on the object. You can also pass it as a parameter to the EditManager in calls to insertGraphicElement and modifyGraphicElement, passing the value for float as an “option” parameter. Lastly you can import it as markup in a TextFlow, using the examples from the end of the blog entry.

  8. Ali Tan Ucer says:

    Hi,How about images that are not rectangle or are you planning to support transparent images with alpha support floated properly (text around not transparent parts of the image). This will be aligned with InDesign image float (or should i say text wrap around the image) support (might be implemented in FXG for better compatibility). I really like to see more professional version of image floating like in InDesign rather than classic HTML version. Otherwise what is the point of re-inventing the wheel if the Flash TLF is a similar to HTML rendering.If the image floating or text wrapping around image is identical with InDesign and if this feature is part of FXG markup that will be a dream come true.

  9. Pingback: TextField mit <img> erzeugt leerzeichen - Flashforum

  10. simple says:

    I add the float attribute, but the image disappear.

  11. Ankur Arora says:

    Hi,
    We are trying to implement image float with text in Flash Builder 4. But when we add float=”left” or whatever out of 3 attributes. It just gets disappeared. Any idea or Help ?

    Thanks
    Ankur

  12. Alan Stearns says:

    Ankur or simple – could you provide more details? Could you post a code snippet?

  13. Tahereh says:

    1 . It seems that paddingBottom changes according to
    fontSize (or lineHeight?) How to prevent this?

    2 . In code bellow if I copy/cut the inlineGraphicElement
    I can not paste it somewhere else in container

    3 . Is there any way to center an image for example and
    have text lines on both sides? (p.clear=both ,
    gr.float=center?)

    4 . BTW How do you know if a selection change event is
    dispatched after text formatting or changes in selection?

    var em:EditManager= new EditManager()
    var ctrl:ContainerController=
    new ContainerController(bg,bg.width,bg.height)//bg:MovieClip instance on stage

    var tf:TextFlow= new TextFlow()
    tf.textAlign=flashx.textLayout.formats.TextAlign.JUSTIFY
    tf.textAlignLast=flashx.textLayout.formats.TextAlign.START
    tf.fontFamily=”arial”
    tf.fontSize=62
    tf.paddingBottom=tf.paddingLeft=tf.paddingRight=tf.paddingTop=15

    var p:ParagraphElement= new ParagraphElement()
    p.clear=flashx.textLayout.formats.Clear.BOTH

    var gr1:InlineGraphicElement= new InlineGraphicElement()
    gr1.float=flashx.textLayout.formats.Float.LEFT
    gr1.source=drawsp()
    gr1.paddingBottom=gr1.paddingLeft=gr1.paddingRight=gr1.paddingTop=10

    var gr2:InlineGraphicElement= new InlineGraphicElement()
    gr2.float=flashx.textLayout.formats.Float.LEFT
    gr2.source=drawsp()
    gr2.paddingLeft=gr2.paddingRight=gr2.paddingTop=gr2.paddingBottom=10

    var s:SpanElement= new SpanElement()
    s.text=”span”

    p.addChild(s)
    p.addChild(gr2)
    p.addChild(gr1)
    tf.addChild(p)

    tf.interactionManager=em
    tf.flowComposer.addController(ctrl)
    tf.flowComposer.updateAllControllers()

    function drawsp():Sprite{
    var sp:Sprite= new Sprite()
    sp.graphics.beginFill(0xcc6565)
    sp.graphics.drawRect(0,0,160,260)
    sp.graphics.endFill()
    return sp
    }

    TIA

  14. Karn says:

    Hi,

    My question might not be related to image things. I would like to know when the TLF team plans to release the support for Tables ? Many thanks

    Karn

    • Alan Stearns says:

      Unfortunately tables are going to take a while to get to. They are not planned for the next CS release, but we hope to get to them for the CS release after that.

  15. daslicht says:

    Hello,
    are any live/demo examples online to study ?
    If not anyone like to put one up, please.
    I have to less capacity at the moment to figure it out at this time since I am in the middle of a BIG project. After that I have more time to have a look on it into depth.
    But I would love to see it in action now 🙂

    Thank you very much for reading and have a nice day.
    Marc

  16. daslicht says:

    …could we make a image dragable and have live textflow around an image ?

    How about the ability to click an image, is that now easier possible than in TLF1, if not please include it, this feature is usefull to make clikc images zoom in or out for example ?

  17. stu says:

    Cannot get an img to float no matter what I try.
    An example would be helpful.

  18. David says:

    When I run my example locally I cannot get an image to display in the TLF container. Any thoughts?

    var externalFileContent:XML;
    var textContainer:Sprite=new Sprite();
    this.addChild(textContainer);
    textContainer.x = 0;
    textContainer.y = 0;

    var textFlow:TextFlow = new TextFlow();
    var loader:URLLoader = new URLLoader();

    loadFile();

    function loadFile():void{
    loader.addEventListener(Event.COMPLETE, loadComplete);
    loader.addEventListener(IOErrorEvent.IO_ERROR, loadError);
    loader.load(new URLRequest(“textFlow.xml”));
    }

    function loadError(e:IOErrorEvent):void {
    trace(“Error loading external file.”);
    }

    function loadComplete(e:Event):void {
    externalFileContent = new XML(loader.data);
    loader.removeEventListener(Event.COMPLETE, loadComplete);
    loader.removeEventListener(IOErrorEvent.IO_ERROR, loadError);
    initText();
    }

    function initText():void {
    textFlow = TextConverter.importToFlow(externalFileContent,TextConverter.TEXT_LAYOUT_FORMAT);
    textFlow.flowComposer.addController(new ContainerController(textContainer, 350, 200));
    textFlow.flowComposer.updateAllControllers();
    }
    And this is the XML (taken from the online text editor on Adobe):

    (where icon.png is in the same directory as the swf)

  19. David says:

    Oh I guess I can’t post XML? Imagine this is well formatted XML:

    flow:TextFlow whiteSpaceCollapse=”preserve” xmlns:flow=”http://ns.adobe.com/textLayout/2008″>flow:p>flow:img height=”auto” width=”auto” source=”icon.png”/>flow:span>/flow:span>/flow:p></flow:TextFlow

    • Alan Stearns says:

      The image hasn’t finished loading by the time you call updateAllControllers. Try adding this line in initText:

      textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,statusChangeHandler,false,0,true);

      Then this function to recompose once the image has loaded:

      function statusChangeHandler(e:Event):void
      {
      textFlow.flowComposer.updateAllControllers();
      }

  20. David says:

    Yep, that did it. That seems like something that should be specifically called out in the the help or docs somewhere. Much appreciated.

  21. Sean says:

    What is the default value for whitespacecollapse of a TLFTextField? I try to change it to collapse but it does not work.

    var format:TextLayoutFormat= new TextLayoutFormat()
    format.whiteSpaceCollapse=WhiteSpaceCollapse.COLLAPSE

    //txt.textFlow.whiteSpaceCollapse=WhiteSpaceCollapse.COLLAPSE

    txt.textFlow.hostFormat=format
    txt.textFlow.flowComposer.updateAllControllers()

    trace(txt.tlfMarkup)
    trace( TextConverter.export(txt.textFlow,TextConverter.TEXT_LAYOUT_FORMAT,ConversionType.STRING_TYPE) )

    Help pls!

  22. Marc says:

    Anyone like to popst some live , working examples, please?

  23. Marc says:

    How about click-able Float-Images, so that we can zoom-in, or popup ?

    • Robin Briggs says:

      A float can be any kind of DisplayObject, so it should be possible to make one that is clickable, etc. Either the float can provide its own interactivity, or you could put the float in a element and register with the for rollovers.

  24. Is it only possible to add floats that are part of the textFlow, ie. text flows around images that move if text before it is changed?
    Is it possible to add text flow around DisplayObjects that are not part of the text flow and doesn’t move when text is change, the same way textWrap is handled in InDesign?

    I’ve make a version myself based on TLF 1.1, but that is restricted to flowing around boxes that are the same width as a text container to avoid uneven line heights

  25. Dinesh says:

    I am not able to get InlineGrpahicElement when i used flaot property in image. My code is:

    htmlFlowReference.textFlow.addEventListener( SelectionEvent.SELECTION_CHANGE, selectionChangeListener, false, 0,true);

    Listener function

    public function selectionChangeListener(event:SelectionEvent):void
    {

    var cTF:TextFlow = event.selectionState.textFlow;

    // slect the correspondent managers for this selection
    if( selectManagersByTextFlow( cTF ) == false )
    return;

    selectionState = event.selectionState;
    selectedElementRange = ElementRange.createElementRange(selectionState.textFlow, selectionState.absoluteStart, selectionState.absoluteEnd);

    trace(‘selectionChangeListener: ‘ + selectionState.absoluteStart + ‘->’ + selectionState.absoluteEnd);
    // set display according to the values at the beginning of the selection range. For point selection/characterFormat use getCommonCharacterFormat as that tracks pending attributes waiting for the next character
    characterFormat = textFlow.interactionManager.activePosition == textFlow.interactionManager.anchorPosition ? textFlow.interactionManager.getCommonCharacterFormat() : selectedElementRange.characterFormat;
    paragraphFormat = selectedElementRange.paragraphFormat;
    containerFormat = selectedElementRange.containerFormat;

    var linkString:String = “”;
    var linkTarget:String = “”;
    var linkEl:LinkElement = selectedElementRange.firstLeaf.getParentByType(LinkElement) as LinkElement;
    if (linkEl != null){
    var linkElStart:int = linkEl.getAbsoluteStart();
    var linkElEnd:int = linkElStart + linkEl.textLength;
    if (linkElEnd < linkElStart){
    var temp:int = linkElStart;
    linkElStart = linkElEnd;
    linkElEnd = temp;
    }

    var beginRange:int = selectedElementRange.absoluteStart;
    var endRange:int = selectedElementRange.absoluteEnd;

    var beginPara:ParagraphElement = selectedElementRange.firstParagraph;
    if (endRange == (beginPara.getAbsoluteStart() + beginPara.textLength)){
    endRange–;
    }

    I have to resize the image but i am unable to test this statement:

    if(selectedElementRange.firstLeaf is InlineGraphicElement){}

    • Jin Huang says:

      I think the question on the forum is also from you. I answered it there. We can continue the discussion on the forum. Sorry for the late reply.