One finger to pan, two fingers to zoom
Lua Carousel » Devlog

Today I'm learning to implement some gestures we take for granted on mobile devices.
v ={x=0, y=0, w=Safe_width, h=Safe_height, zoom=1.0} -- viewport
f,s = nil -- ids of first and second touches
start, curr = {}, {} -- coords of touches by id
initzoom = nil
initpos = nil -- for panning
function car.draw()
color(1,0,0)
rect('fill', vx(100), vy(100), scale(400), scale(200))
color(0.5, 0.5, 0.5)
for _,touch in ipairs(touches()) do
if curr[touch] then
circle('fill', curr[touch].x, curr[touch].y, 10)
end
end
end
function car.touchpressed(id, x,y, ...)
if f == nil then
f = id
initpos = {x=v.x, y=v.y}
else
s = id
initzoom = v.zoom
end
start[id] = {x=x, y=y}
curr[id] = {x=x, y=y}
end
function car.touchreleased(id, x,y, ...)
f,s = nil
start, curr = {}, {}
initzoom = nil
initpos = nil
end
function car.touchmoved(id, x,y, ...)
if start[id] then
curr[id] = {x=x, y=y}
if s then
v.zoom = dist(curr[f], curr[s])/dist(start[f], start[s])*initzoom
elseif f then
v.x = initpos.x + start[f].x - x
v.y = initpos.y + start[f].y - y
end end end
function vx(sx)
return scale(sx-v.x)
end
function vy(sy)
return scale(sy-v.y)
end
function scale(d)
return d*v.zoom
end
function dist(p1, p2)
return ((p2.x-p1.x)^2 + (p2.y-p1.y)^2) ^ 0.5
end
function str(s) return tostring(s) end
65 lines (though itch.io keeps deleting the blank lines I paste in)
If you try pasting this program into Lua Carousel, remember to first run the abbreviations on one of the example screens. Or if you've deleted that screen, here are the abbreviations I used in this post:
g = love.graphics rect, circle = g.rectangle, g.circle color = g.setColor touches = love.touch.getTouches
Get Lua Carousel
Lua Carousel
Write programs on desktop and mobile
| Status | In development |
| Category | Tool |
| Author | Kartik Agaram |
| Tags | LÖVE |
More posts
- Programming on your device with your preferred language84 days ago
- Lua Carousel: program on the device you have, with docs at your fingertipsMay 12, 2025
- Pong Wars, MMO editionFeb 16, 2025
- New version after 41 days, and stop-motion animationFeb 15, 2025
- Drawing with a pen on a pendulumJan 11, 2025
- New version after 16 daysJan 04, 2025
- New version after 9 daysDec 19, 2024
- New version after 3 daysNov 17, 2024
- New version after 40 daysNov 14, 2024
- Turn your phone or tablet into a chess clockNov 01, 2024
Comments
Log in with itch.io to leave a comment.
Zoom to the screen middle point, to the middle of multiple touches or to the top left corner?
That is a good question, if I understand you right. The above program keeps the top-left corner of the viewport fixed. Is that what you meant?
Since then I made a change to it to keep the centroid between fingers fixed:
function car.touchmoved(id, x,y, ...) if start[id] then curr[id] = {x=x, y=y} if s then local oldzoom = v.zoom v.zoom = dist(curr[f], curr[s])/dist(start[f], start[s])*initzoom adjust_viewport(oldzoom, v.zoom) elseif f then v.x = initpos.x + iscale(start[f].x - x) v.y = initpos.y + iscale(start[f].y - y) end end end function adjust_viewport(oldzoom, zoom) -- ensure centroid of fingers remains in view local c = centroid(curr[f], curr[s]) v.x = v.x + c.x/oldzoom - c.x/zoom v.y = v.y + c.y/oldzoom - c.y/zoom end function centroid(a, b) return{x=(a.x+b.x)/2, y=(a.y+b.y)/2} end function iscale(d) return d/v.zoom end