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 Animated, Easing, Flex 3, ScrollBar, Smooth, Tween




5 Comments
Hi, is there a Solution with an MouseWheel?
Dude this great! thanks for the post!!
Thats class, good man.
Hi
I found a different approach for the same effect (much shorter but maybe not better) .
Add a listener to the scrollContainer:
scrollerContainer..addEventListener(ScrollEvent.SCROLL, onCanvasScroll);
And in that listener use a Caurina tween:
Tweener.addTween(viewContainer, {verticalScrollPosition:scrollerContainer.verticalScrollPosition, time:0.7, transition:”linear”});
And thats it. Will put a demo on my blog if anyones interested.
Ported to Caurina/Flex from a Flash version on http://www.soundstep.com/blog/experiments/scrollpane/
Incoming Links
Leave a Reply