Mastering the Tao of Personal Computing

my del.icio.us: ArticleS.UncleBob.TheThreeRulesOfTdd: Every programmer needs to bookmark this one http://bit.ly/6jONm 12 hrs ago

Flex 3 Animated Scrolling (a.k.a. Smooth Scroll)

Oct 24th 2009
One Comment
respond
trackback

Almost year and a half ago I’ve wrote an article about making a pretty custom scroll-bar with a Fixed Sized Scroll-Thumb - a task known in the community as a designer scroll-bar. Both blog posts proved to be useful, but just recently I received an email from this very cool guy Dino from Canada with the following question.

Dino wrote:
I was also wondering how would I go about adding easing to the scrolling of a VBox? I don’t think there is an out-of-box solution such as an Accordion having a style property openEasingFunction that allows you to specify easing but I could be wrong. Does this require customization of the Container class? I was looking at Container.scrollChildren() and other methods in the Container class to determine if I could override any behaviour.

Somehow his email coincided with a scroll-related task I had recently. I had to use a scroll-bar which is situated on a pretty custom position and it was strolling columns of content with a snapping effect. So, how would I approach the problem with the animated scroll-bar?

The Solution

Going for extending the Container or some of the others Flex containers is a hairy and let’s say adventurous direction to proceed with. And I believe the solution won’t be much flexible. What would you do if you need to place the scroll-bar on a more peculiar place (e.g. on the left or the top side of the container sizes or event somewhere else outside the scrolled container)?

The solution is to detach the scroll-bar from the container, so we can use an outside scroll-bar. The following code fragment shows you how to achieve this:

<!-- 1. Place the View that needs scrolling into a Canvas which represents the visible area
     which can't be exceeded by the View.
     !!!IMPORTANT!!! Disable the scrolling of the Canvas, so we can use a detached scroller,
     which we can place wherever we want (e.g. on the left or top sides of the Canvas) -->
<mx:Canvas id="viewContainer"
    width="{largerView.width}" height="500"
    verticalScrollPolicy="off" horizontalScrollPolicy="off"
    borderColor="black" borderStyle="solid">
    <view:ViewThatNeedsScroll id="largerView"/> <!-- THIS IS THE VIEW -->
</mx:Canvas>

<!-- 2. Create a Canvas with fictive content - this is the actual detatched scroll-bar.
     Make sure the dimensions of this Canvas are corresponding to the size of the visible
     area specified by the View-container. Also make sure the fictive content has dimensions
     corresponding to the the dimensions of the View.
     Use data binding to set the corresponding dimensions! -->
<mx:Canvas id="scrollerContainer"
    x="{viewContainer.x - scrollerContainer.width}"
    y="{viewContainer.y}"
    width="40" height="{viewContainer.height}">
    <mx:Canvas width="1" height="{largerView.height}"/> <!-- THIS IS FAKE CONTENT -->
</mx:Canvas>

The Simplest Way to Attach the Scroll-Bar to the View

Before trying to add a tween and an easing to the scrolling motion, I’ll show you the most simplest solution for attaching this outer scroll-bar to the View that needs to be scrolled:

<!-- 3. Use Data Binding to attach the scroller to the View: -->
<mx:Binding source="scrollerContainer.verticalScrollPosition"
    destination="viewContainer.verticalScrollPosition"/>

Here’s the working sample (view source is enabled):

Animating the Scrolling

I’ve implemented a simple controller component which animates the scrolling movement. You can adjust various properties of the ScrollerController, such as:

● interaction delay
● easing function
● max duration of the tween
● etc.

I’m not going to look at the controller’s implementation in details. Feel free to ask me any questions in the comments section.

Here’s the working sample (view source is enabled):

Tell me what do you think of my solution? How would you solve this problem?


This post is tagged , , , , ,

One Comment

  1. Grey

    Hi, is there a Solution with an MouseWheel?

Incoming Links

Leave a Reply