Math for a Scrollbar?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Math for a Scrollbar?

Post by BruceTheGoose »

Can't figure it out.

Here is my code

Code: Select all

self.update = function(dt)

		local mx = love.mouse.getX();
		local my = love.mouse.getY();
		
		-- The ratio between the height of the viewport and the height of the content
		local contentRatio = self.h / (50 * #content)
		
		
		if(self.mouseDown) then
		
		-- mpD is the difference between the current mouse position and the recorded mouse position when the grip was clicked
			local mpD = my - self.mousePos
			
			self.scrollbarY = self.scrollbarY + mpD * (#content * dt)
		end

-- Calculate height of scrollbar
		self.scrollbarH = (self.h * contentRatio) / scale


-- Limit Size of Grip
		if(self.scrollbarH < 20) then
			self.scrollbarH = 20 / scale
		end

		if(self.scrollbarH > self.h) then
			self.scrollbarH = self.h / scale
		end

		if(game.state == self.state ) then
-- I suspect the issue is here
			content.y =  (self.h - self.scrollbarY) * ((#content * 50) / self.h ) / scale
			
			for i,v in ipairs(content) do
				v.y = (content.y + (i * 50)) * scale
				v.x = self.x + self.w - content[i].w/2 
			end
			
			-- Boundaries
			if(self.scrollbarY < self.y) then
				self.scrollbarY = self.y
			elseif(self.scrollbarY + self.scrollbarH > self.y + self.h) then
				self.scrollbarY = self.y - self.scrollbarH + self.h
			end


		end
	end
	
I don't know what im doing wrong.
Attachments
Screen Shot 2017-02-23 at 11.03.21 PM.png
Screen Shot 2017-02-23 at 11.03.21 PM.png (27.5 KiB) Viewed 4214 times
"I don't know."
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: Math for a Scrollbar?

Post by evölbug »

in my GUI library I use this for scrolling

Code: Select all

-- approach function
function approach(curr, goal, step)
    if curr+step >= goal then
        return step>0 and goal or curr+step
    else
        return step<0 and goal or curr+step
    end
end

Code: Select all

-- scroll code
if scrollY>0 then -- scroll down
    if object.y <= 0 then
        object.y = approach(object.y, 0, speed)
    else -- scroll up
        if object.y >= container.h - object.h
    end
end
object.y = approach(object.y, container.h - object.h, -speed)

Code: Select all

-- scrollbar code
barHeight = container.h / (object.h / container.h)
barY = -object.y / (object.h / container.h)
container is the container (viewport) that your object is scrolled inside in
object is the object that's scrolling
speed is the scrolling speed

with none to a little tweaking it should work for you
User avatar
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Math for a Scrollbar?

Post by BruceTheGoose »

It would be helpful with more context. Could you share the whole file?
"I don't know."
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Math for a Scrollbar?

Post by ivan »

Bruce, I think there might be a simpler way to program scrollbars.
What you have here is sometimes called a "slider" knob which is the middle part of the scrollbar without the arrow buttons.
For starters, make the scrollbar instantly jump to the target position as soon as the user clicks.
It doesn't need to be 'smooth' scrolling, just snap the position in segments.
Your slider can have N possible positions (or segments) where N should be between 1 and the number of elements.
Storing the y-position (or the "value") of the slider in this way is much simpler/cleaner.
Then you can introduce stuff like mpD - you're on the right track there,
although I would have called it something like mouse "offset".
Note that you can do all of these calculations in the mouse press callback.
Use the update function and delta to introduce smooth scrolling and possibly inertia for touch events.
And don't hardcode magic values like: "#content * 50" use the font height/metrics in your calculations.
As a final touch you can have a composite 'scrollbar' object which includes a slider and the two buttons,
where the point is reusing the existing code for your 'button' object.

This is from an old project I had worked on:

Code: Select all

function slider:mouse_press(button, x, y)
  -- convert mouse position to segment/value
  -- assuming x y are in local coordinates
  local v
  if self.horizontal == true then
    v = x/self.width * self.segments
  else
    v = y/self.height * self.segments
  end
  self.value = math.ceil(v)
end
Once you know the "value" of the slider the rest is relatively straightforward:

Code: Select all

  -- dimensions of the slider
  local w, h = self.width, self.height
  -- number of segments
  local s = self.segments
  assert(s > 1) -- prevent division by 0
  -- let's calculate the knob size (vertical or horizontal)
  local knob
  if self.horizontal == true then
    knob = math.max(w/s, MIN_KNOB_SIZE)
  else
    knob = math.max(h/s, MIN_KNOB_SIZE)
  end
  -- let's calculate the knob position (relative to the top-left corner of the slider)
  local ratio = (self.value - 1)/(s - 1)
  -- the center position of the knob
  local x, y = w/2, h/2
  if self.horizontal == true then
    local v = math.max(w - knob, 0)*ratio
    x = v + knob/2
  else
    local v = math.max(h - knob, 0)*ratio
    y = v + knob/2
  end
  -- we now know the CENTER position of the knob
  -- relative to the top-left corner of the slider
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: Math for a Scrollbar?

Post by evölbug »

BruceTheGoose wrote: Sat Feb 25, 2017 3:55 am It would be helpful with more context. Could you share the whole file?
The whole file won't help you much, as it is written in moonscript and it's component oriented. The excerpts are the pure functionalities of two components - the scroller (what does the actual content scrolling) and scrollbar itself. Although, I have just realised you want to move the content using the scrollbar, while I use mine as just a display of what part of the content you are viewing. :o:
Post Reply

Who is online

Users browsing this forum: No registered users and 103 guests