View Full Version : AS3 Inverted Scrollbar
nico
July 10th, 2009, 02:20 PM
Hello AS3 gurus. Is it possible to create an inverted scrollbar? Because Im populating an empty movieclip with data and i want to scroll this data using a scrollbar, but instead of populating from the TOP TO BOTTOM Im populating the movieclip from the BOTTOM UPWARDS. Im having problems with my scrollbar if i did it this way. But if i populate the empty mc with data from TOP to BOTTOM, my scrollbar is working properly.
Any hints/ideas ?
Thanks!!!
nico
July 10th, 2009, 02:22 PM
I also tried to reverse all the values of my scrollbar code (ie: make it negative, change the scrollbar registration point to bottom left, etc etc) but it seems im really missing a step or im doing it wrong. I believe there's a solution to my problem.
Any help is greatly appreciated! :D
IQAndreas
July 10th, 2009, 02:33 PM
Could you post whatever code you have?
Try just populating the scroll component from bottom to top, then move the actual "scroll bar" all the way down to the bottom.
Or do you mean, scrolling the bar up will scroll the contents down and vice versa?
nico
July 10th, 2009, 02:58 PM
Could you post whatever code you have?
Try just populating the scroll component from bottom to top, then move the actual "scroll bar" all the way down to the bottom.
Or do you mean, scrolling the bar up will scroll the contents down and vice versa?
You got it IqAndreas! The scrollbar thumb will start at the bottom. By dragging the scrollbar thumb upward, it will scroll the contents down, and by dragging the scrollbar thumb downward, it will scroll the contents up.
I really want to do this because the data is appearing and populating the movieclip starting from the bottom upwards: (ie inside a forloop: mc.y = mc.y - (mc.height * i)).
I have the working scrollbar implemented. It can scroll contents the typical way. I thought making it work in reverse is just simple, but i tried it using my common sense and still its not working. maybe there's some kind of code i need to put.
Here's the code for the MOUSE_MOVE event of my scrollbar thumb:
function sbMove(e:MouseEvent):void
{
scroll_percent = sfm.sb.thumb.y / y_max;
sfm.sb.thumb.y = mouseY - y_offset;
if(sfm.sb.thumb.y <= y_min)
{
sfm.sb.thumb.y = y_min;
}
if(sfm.sb.thumb.y >= y_max)
{
sfm.sb.thumb.y = y_max;
}
//this is the actual code for the scrolling content
TweenLite.to(sfm.sub_nav_container, .3, {y:(-scroll_percent * (sfm.sub_nav_container.height - sfm.sub_nav_mask.height ))});
e.updateAfterEvent();
}
IQAndreas
July 10th, 2009, 03:05 PM
Okay. I only glanced at the code, and I only have a few seconds right now, but here is what you could do.
I see you have the "scroll percent" amount figured out. (I'm guessing you are using "1" as 100%, not 1%. Am I right?)
To scroll backwards, the MovieClip's scroll percentage should be "1 minus the scroll bar percentage". This might work, but when I have more time I will inspect your code closer.
TweenLite.to(sfm.sub_nav_container, .3, {y:((1-scroll_percent) * (sfm.sub_nav_container.height - sfm.sub_nav_mask.height ))});
That might or might not work, but do you understand the general idea behind it?
nico
July 10th, 2009, 03:19 PM
Thanks for the quick reply iqandreas. Hmmm honestly that 1 minus the scroll percent didn't enter my mind. But now that you mentioned it, there's a sense into it. I'm really not good on algorithms hehe. I need to try this and test it if it'll work.
Do mc registration point matters in my problem? Because a typical scroll bar's registration point is at the top left.
Anyway, thanks much for your help. I'll try this out first. I'll keep you posted friend:)
IQAndreas
July 10th, 2009, 03:25 PM
You are right. I didn't think of mc registration.
Upload the files or send them to me and I'll take a look at it next break.
nico
July 11th, 2009, 01:15 AM
Thanks! I attached the working prototype file. This file will explain what im trying to accomplish :)
Thank You! :D
IQAndreas
July 11th, 2009, 04:06 AM
Finally finished.
It is now 3AM, but I just couldn't put it down until I was done.
It's all a little crude, and I could have coded it better, but it will work for your needs. I also made the "slice" design a little more nice. Make sure to always add all objects above y=0. Anything below 0 (a y value of 1 or more) will be cut off. I also made the thumb bar change size depending on how many items are in the container.
Enjoy, just paste this into frame 1:
import gs.TweenLite;
var y_offset:Number;
var y_max:Number = sb.track.height - sb.thumb.height;
var y_min:Number = 0;
var scroll_percent:Number;
var num_of_strips:Number = 10;
var containerMinY:Number = content_mask.height;
var containerMaxY:Number = 0;
sb.thumb.addEventListener(MouseEvent.MOUSE_DOWN, startScroll);
function startScroll(e:MouseEvent):void
{
if (container.height <= content_mask.height)
{
//Do nothing, as the scroll bar won't move it anything anyway.
}
else
{
y_offset = mouseY - sb.thumb.y;
stage.addEventListener(MouseEvent.MOUSE_MOVE, updatePos);
}
}
stage.addEventListener(MouseEvent.MOUSE_UP, endScroll);
function endScroll(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, updatePos);
}
function updatePos(e:MouseEvent):void
{
sb.thumb.y = mouseY - y_offset;
updateContainerPosition();
}
function updateContainerPosition():void
{
if(sb.thumb.y >= y_max)
{ sb.thumb.y = y_max; }
if(sb.thumb.y <= y_min)
{ sb.thumb.y = y_min; }
scroll_percent = sb.thumb.y / (y_max - y_min);
var newY:Number = ((1 - scroll_percent) * (containerMaxY - containerMinY)) + containerMinY;
//trace(containerMaxY, containerMinY, newY);
TweenLite.to(container, 1, {y:newY});
}
function initStrips():void
{
container.mask = content_mask;
for(var i:uint = 1; i <= num_of_strips; i++)
{
var strip:Strip = new Strip();
strip.alpha = 0;
strip.y = -1 * (strip.height + 5) * i;
TweenLite.to(strip, 1, {alpha:(0.5) + (0.5 * ((num_of_strips - i) / num_of_strips)), delay: i * .3});
container.addChild(strip);
}
updateThumbSize();
}
//Make the thumb adjustable depending on how much is inside of container.
function updateThumbSize():void
{
if (container.height <= content_mask.height)
{
sb.thumb.height = sb.track.height; //Maximum possible height
sb.thumb.y = y_min;
//Update maximum and minimum values
y_max = sb.track.height - sb.thumb.height;
//y_min always stays 0
//Align container to bottom
container.y = containerMinY;
containerMaxY = containerMinY;
}
else
{
containerMaxY = containerMinY + ((-1 * container.getBounds(container).top) - content_mask.height);
y_max = sb.track.height - sb.thumb.height;
updateContainerPosition();
}
}
initStrips();
Just ask if you have any questions with anything.
nico
July 11th, 2009, 04:26 AM
Thank you very much iqandreas. YOURE THE BEST MAN!!! Im now looking into your code and studying it. This is perfect and the right effect im looking for.
Thanks again!!!! :D
nico
July 11th, 2009, 09:35 AM
Hi iqandreas :D I just noticed that the content is somewhat scrolling a few pixels down? did you notice it? What part of the code will i change to remove this? :) The algorithm of your code is too advanced for me to comprehend hahahaha. but im starting to understand :) Thanks!
IQAndreas
July 12th, 2009, 12:12 AM
Yes, I noticed that too, and I'm pretty sure I know what's causing it. :P
I will have to extend the code even further to fix this (ugh), and right now I don't really have the mental power or the time. I'm also in the middle of moving.
Is this code very important, or can it wait? If it can wait, in one more month, I will have all the free time in the world (yipee!) so if the code is still important then, send me a message and I will take a look at it and try to tackle it once more.
Actually, I have one idea that might serve as a bandaid for now. Try replacing this line with this:
strip.y = (-1 * (strip.height + 5) * i) - 5;
I'm not sure if I'm thinking backwards now or not, but I think it might work.
Good luck with your future programming,
Andreas
nico
July 12th, 2009, 01:26 AM
Hello friend :D i managed to fix the issue where the content is moving a few pixels downward :) well, i just subtracted the total height of the strip im adding to the containerMinY variable. It fixed that issue.
I consider this as a bandaid also hehe :)
new_y = ((1 - scroll_percent) * (container_max_y - (container_min_y - 30))) + (container_min_y - 30) ;
Can i ask one last favor. I want to add a blur to my inverted scrollbar. I used the onUpdate event of TweenLite but it isnt the effect im trying to make. I want it to blur based on the speed of how your scroll the content. Can you give me some hints/tips/algorithm on how to accomplish this.
How I wish i have that strong mental power as yours :) Im a designer btw :)
Thanks Friend, you're a great help and i will remember your ID/Name :D
IQAndreas
July 12th, 2009, 02:29 AM
Well, I haven't used TweenFilterLite (http://blog.greensock.com/tweenfilterliteas3/) yet, but I think it can be done something like this:
var newY:Number = ((1 - scroll_percent) * (containerMaxY - containerMinY)) + containerMinY;
//Figure out how far you are you are scrolling. The more scroll in the 1 second scroll tween, the more the blur should be.
var dist:Number = Math.abs(newY - container.y);
TweenFilterLite.to(container, 0.5, {blurFilter:{blurX:dist, blurY:dist}});
TweenFilterLite.to(container, 0.5, {delay:0.5, blurFilter:{blurX:0, blurY:0}}); //De-blur back
TweenLite.to(container, 1, {y:newY});
That might work. Perhaps you need to tweak the blur settings a bit to only half of the distance or something.
Not sure. Give it a go.
Andreas
nico
July 12th, 2009, 06:16 AM
Thanks for the tip iqandreas, ill try this up and keep you posted :) thanks for all the help :D
nico
July 12th, 2009, 10:17 AM
Hello Friend :) Your formula works for the blur. The blur is a bit strong though so i divided it with some random big number.
Im really studying your code right now (because i want to be a great programmer like you :)).
Im just curious on this code:
container_min_y = to the total height of the mask.
container_max_y = 0;
container_max_y = container_min_y + ((-1 * sfm.sub_nav_container.getBounds(sfm.sub_nav_contai ner).top) - sfm.sub_nav_mask.height);
The formula is a bit complicated and i seem to understand it but not full. If you have time, can you explain this chunk of code. Im really shy right now with you, i hope im not asking too much :)
IQAndreas
July 13th, 2009, 12:11 AM
This line of code uses the getBounds() function.
sfm.sub_nav_container.getBounds(sfm.sub_nav_contai ner).top
Basically, the problem was, the code was adding the first button at -50, not zero. So let's say, after you have added all of your squares, the final (tenth) square you place is at -550. This is alright. The problem is, if you try to get the height of the container, you get "500". This is great, but the problem is, when you scroll all the way up, you cut off about 50 pixels from one square.
So to solve that problem, I used the getBounds().top function. Basically, it says, the top most side of the box is at "-550 pixels". So, if I set the maximum possible Y to 550 pixels, the movie clip will never scroll past that.
It's kindof tricky to describe what getBounds() does without drawing it out (I'll put that on my todo list), but I can try to explain more if you want me to. Here is a link that describes it more:
http://livedocs.adobe.com/flex/2/langref/flash/display/DisplayObject.html#getBounds() (http://livedocs.adobe.com/flex/2/langref/flash/display/DisplayObject.html#getBounds%28%29)
I was pretty sloppy and quick when working, and should have made it clearer.
Now I think I also figured out why that whitespace was at the bottom. (Silly me :P ) I think I might have assumed it was supposed to be zero, when in fact, it should have been getBounds.bottom or someting.
My mind is far to slow (and tired) right now to think it all through, and to be truthful, I can't really remember why I did most of that. You see, my mind alternates between super productivity, and slow, basically no progress thinking. Sadly, I can't control when that happens, so when it does happen, I do as much as I can in that short timeframe before it goes away. (It's a gift, and a curse. The worst part is being "down" when I have a huge exam or test lying in front of me, or some project that needs to get done ASAP. :( )
I will take a look at the code again when I am back "up", and see if I can get it to a fully working code that can be used elsewhere as well.
Andreas
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.