• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Basic scroll bar maths

MeBoingus

Member
Hi all,

I've run into a problem while adding a scroll bar to my game. I'm 99% sure that it can be solved with basic mathematics, but for some unknown reason, I'm really struggling.

I have a list of comments being drawn to a surface, vertically. I have a scroll bar that is being drawn at an origin point, plus a variable that is relative to how far we've scrolled through the list.

I'm trying to add the ability to click on the scroll bar and drag in order to scroll through the list.

I use this code:

Code:
var scrollBarH = (commentsSH / commentH) * commentsSH;
var scrollBarY = (+commentScrollY / (commentH - commentsSH)) * (commentsSH - scrollBarH - 20);
To set the height and y position (an offset from its origin point) of the scroll bar.


In other words, If I move the mouse downward by 100 pixels, I need to update the commentScrollY variable to the value it would have if the scroll bar were 100 pixels below its previous position.


Any help would be greatly appreciated!


What each variable in the code means / is set to:
commentsSH - the height of the surface the comments are being drawn in.
commentH - the total height of all of the comments.

scrollBarH - the height of the scroll bar.
scrollBarY - the Y position of the scroll bar.
commentScrollY - the number of pixels we've scrolled (starts at 0, ends at -commentH)
 

NightFrost

Member
The height of the scrollbar would be the height of the window where stuff scrolls, divided by the total height of scroll contents (the surface), times the height of the window. So, if the window is 200 pixels tall and the scrollable content is 800 pixels, the height of the scrollbar is 200 / 800 * 200 = 50 pixels. Which mathces up: since the scrollable content is four times the size of window, the bar is one quarter the size of window.

The total scrollable length is the height of the window minus the height of the scrollbar, or 200 - 50 = 150 pixels. When the bar has moved 150 pixels down, the window should show the very bottom of the content. The top left of the surface at that point should be the height of the content (the surface) minus the height of the window, or 800 - 200 = 600. So when the scrollbar is at the very bottom the window displays pixels 600 to 800 of the surface.

When you drag the scroll bar, the surface moves at the ratio of those heights. Dragging it down 50 pixels means (50 / 150) * 600 = 200 pixels down the surface, or a quarter down as it shoud. And dragging to the very bottom means (150 / 150) * 600 = 600 pixels down on the surface.
 

The basic math is pretty simple. There are a couple of ratios, view_y over (world_h - view_h), and handle_y over (scrollbar_h - handle_h). Those ratios should be equal, which can be used to easily solve for handle_y or view_y.

But there are a couple of gotcha's having to do with divide by zero errors or clamping issues when the height of the world is equal or smaller than the height of the view....

view_y to handle_y....
Code:
if(world_h > view_h){
    view_y = clamp(view_y,0,world_h-view_h);
    handle_y = (scrollbar_h - handle_h) * view_y / (world_h - view_h)
}else{
    view_y = 0;
    handle_y = 0
}
handle_y to view_y....
Code:
if(world_h > view_h) {
    handle_y = clamp( handle_y, 0, scrollbar_h - handle_h);
    view_y = (world_h - view_h) * handle_y / (scrollbar_h - handle_h)
} else {
    handle_y = 0;
    view_y = 0
}
You'll probably want the height of ths scrollbar handle to reflect the proportion of the world seen through the view.
But you'll also want to make sure it has a minimum height so that the user doesn't have trouble seeing/interacting with it.
Make sure the minimum handle height is smaller than the scrollbar's total height....
Code:
if(world_h > view_h)
    handle_h = max(handle_min_h,scrollbar_h * view_h / world_h);
else
    handle_h = view_h
 
Last edited:

Joe Ellis

Member
The scrollbar itself has 2 main variables:
The height\length of the scrollbar
and the position of the scrollblock

The position of the scrollblock in between the top and bottom of the scrollbar creates a ratio:

ratio = (scrollblock.y - scrollbar_top_y) / scrollbar_height

Then you can use this ratio to set the "scroll_y" variable in the main browser object:

scroll_y = scroll_height * ratio

"scroll_height" is the height of the area your scrolling up & down, and scroll_y can be used to set the view\projection and things, and the width & height will = the width and height of the actual area the scrolling area covers on the screen.
 
Top