Organic Scroller Preview Part II
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.