Paul created a cool demo to explore some of the new features in TinyTLF V2.0 (still in beta). The circular region demo (yes, we can do the equivalent of CSS Regions right now in Flash) has been expanded.
Check out the blog post here and enjoy!
Update: For those who have asked, a new version of the demo with text constrained by spline boundaries is in the works, but scheduled for after the V2 formal release.
I’ve given several Freehand drawing demos on my iPad-2 here at MAX, but one of the things I’ve failed to mention is the impending release of TinyTLF V2.0. You can read about the new features and implementation details here.
Paul and I recently collaborated on another organic text layout demo. I really like it when Paul does all the hard work and I come in at the tail end and wrangle some equations (a bit of analytic geometry). Where do I get more gigs like that?
Anyway, here’s a demo of the new layout algorithm for organic text. Given the even lighter weight of the 2.0 code base, I’m envisioning a lot of interesting mobile applications 🙂
My time on this gig is almost over and I’ve really enjoyed working with this client. It’s also been great to work with a top-flight Flex architect. My responsibilities included overhaul of a massive legacy Flex 3 application using PureMVC and a new Flex 4 learning game.
I’ve mentioned the use of TinyTLF in a prior post, so here is a screen shot of the completed product.
The entire game is implemented as a Flex 4 Skinnable component, with separate skinnable components for the primary game constituents, the most complex of which are the passage display and the vault graphic controller. The former uses TinyTLF for the inline word selector rendering. Word Selectors are injected based on block controller factory classes assigned in the CSS file for this game. The (artist-generated) vault graphic is embedded as a .SWF (not as symbols within a .SWF). The individual symbols are extracted and manipulated either as skin states or as part of invalidating the component.
Different skin classes were substituted for the passage display during the course of development, ranging from customized formatting for different paragraphs to 3D boxes for the selectors. The ease at which these changes were made really emphasizes the benefits of Skinnable Components in Flex 4.
I’ve been extremely busy with a gig the last couple months, so posts have been sparse. This is a quick preview of some work with Paul Taylor’s TinyTLF – http://www.tinytlf.org. Paul and I have collaborated in the past on spline-constained text layout and dynamic scrolling with quad. Bezier splines. While I’ve been keeping up with progress on with TinyTLF, this is my first serious application of the library.
The problem is to render interactive ‘word selectors’ in-line with text, provided in html format. An example input is of the form,
<passage><p>Sarah’s <word>father</word> had died in 1797, two years earlier. Life was difficult with him gone, but the family had learned to <word>adapt</word>. Sarah found that she had to support the family with her daily hard work.</p><p>The family’s main <word>product</word> was cattle, but it also raised chickens—and Sarah had been put in charge of both types of animal. Father had worked hard at <word>farming</word> and building furniture, but that business was <word>defunct</word> now that he was gone. Together, the family survived without him due to their courage, tenacity, and <word>strength</word> of character.</p></passage>
Some passages may contain <b> or <i> tags as well. Everywhere a <word> tag is present, an interactive word selector must be rendered in-line with the text. TinyTLF is used to render the text and the word selectors are rendered by a custom TextBlock factory assigned to the TinyTLF text engine. The factory and the word selectors implement specified interfaces (IWordSelectorBlockFactory and IWordSelector). An event is dispatched when the word selectors are added to the stage, which allows the skinnable component controlling passage display to obtain references to the created IWordSelector.
TinyTLF allows the text to be easily styled by assigning styles, either through an external style sheet or constructed from Flex style properties assigned to the passage display class (the technique I use in this app). The rendered result is shown below after some interaction with the word selectors (the same synthetic data is used across all test passages, so the concept of correct vs. incorrect selection is meaningless in this example).
The really cool thing about programming the skinnable component to a set of interfaces and not specific implementations is the ability to quickly create new block factories and selector implementations. This was actually used to switch out rectangular 2D selectors with Actionscript 3D rectangular boxes.
After this gig is finished, I plan to become a contributor to TinyTLF and hope to create some cool examples for public consumption as well as advance the use of splines in TinyTLF layout.
Short and to the point. Paul Taylor just posted some demos, one of which shows the quadratic Bezier spline used in advanced layout and another showing the organic, spline-based scroller in action. I’ve pretty much decided to write a white paper on the math behind the scroller at some point in the near future.
I have received several questions regarding the organic scroller preview. The code will be released when Paul Taylor releases the final set of TinyTLF demos (layouts are currently being refactored). Our collaborative work will illustrate html text laid out respecting a spline boundary with the right boundary serving as a dynamic scroller component. I’ll provide a brief overview of how the scroller works in this post. A detailed deconstruction is a topic for a later white paper or book chapter.
The boundary spline is a G-1 continuous quadratic Bezier spline. The spline is generally non-interpolative and has a tension parameter. I tend to like 0.3 a lot 🙂 The spline interpolates the first and last points. Interior control points influence the shape of the spline, but the spline does not necessarily interpolate those points. I’ve covered the spline in past posts and its fundamentally the same algorithm I implemented in the Degrafa quadratic spline. As the spline is naturally composed of quadratic Bezier segments, it constructs and renders fast.
The boundary is duplicated and shifted a number of pixels to the right to create the scroller track. The spline is naturally uniform parameterized. If invalidated, the spline is reparameterized on arc length. This is done with a simple heuristic that varies the interpolation granularity based on the length of each spline segment. I will overhaul this heuristic in the future when I release arc-length parameterization for an arbitrary path. For now, it’s a demo, so it’s kept simple. Simple is good 🙂
The scroller thumb length is a fraction in [0,1] representing the fraction of the total boundary spline length to use when rendering the thumb. The component maps the thumb value to arc length in [s1,s2] so that the thumb length is preserved and the midpoint of the thumb (in arc length) represents the thumb value.
Now, for the fun part. The scroller class returns a vector of quadratic Bezier instances representing the path along the boundary from arc length s1 to arc length s2. This is an exercise in deCasteljau subdivision. Subdividing a quadratic Bezier at parameter t produces two independent quadratic Beziers that exactly represent segments of the original curve. The first quadratic represents the original curve in [0,t]. The second represents the original curve in [t,1]. The subdivision code was modified to return coefficients of either segment. That’s fine when s1 and s2 represent points in different quadratic segments. The situation is more subtle when s1 and s2 are in the same quad. This involves refining the original quadratic Bezier in the interval [s1,s2]. Once the vector of quadratic Bezier coefficients is returned, the thumb can be drawn quickly with the usual moveTo(), lineTo(), curveTo().
Interactivity is also an issue. For a vertical scroller, vertical mouse movements do not map linearly into scroller arc length. Attempting to do so may cause the scroller to jump erratically in some configurations. Instead, a quadratic model for mapping vertical mouse movements into thumb value is employed.
I suspect there is still some tweaking to do (isn’t there aways), so I’ll continue to provide updates. In the mean time, the next background project is arc-length parameterization of a general path, which may be both spatially discontinuous and likely discontinuous in first derivative.
Well, I’m leaving Saturday for my very first Adobe MAX. While I’m not too excited about going to LA, it’s going to give me a chance to visit family in Phoenix. If you’re attending, look for the guy in the tennis gear and say hello 🙂
Paul Taylor and I are working on another demo. This one will be even more intense than the organic text we showed at 360|Flex . If you’re interested in finding out more about TinyTLF and want to see what you can do with all that stuff you saw in math class, then look for either the guy in the chair (twitter @guyinthechair) or the guy in tennis gear. See you at MAX!