It looks like you're new here. If you want to get involved, click one of these buttons!
I wanted to figure out a way to implement pinch zoom, and the easiest way was to build off of the multi-touch example.
function setup()
print("This example tracks multiple touches and colors them based on their ID")
-- keep track of our touches in this table
touches = {}
a = nil
b = nil
av = vec2(0,0)
bv = vec2(0,0)
initialDistance = 0
ratio = 1
end
function countTouches()
i = 0
for k,v in pairs(touches) do
i = i+1
end
return i
end
function gatherTouches()
a = {}
for k,t in pairs(touches) do
table.insert(a,t)
end
return a[1],a[2]
end
function between( val, low, high )
return (low <= val and val <= high)
end
function touched(touch)
if touch.state == ENDED then
-- When any touch ends, remove it from
-- our table
touches[touch.id] = nil
if( twoFingerTouch == true ) then
twoFingerTouch = false
initialDistance = 0
ratio = 1
end
else
-- If the touch is in any other state
-- (such as BEGAN) we add it to our
-- table
touches[touch.id] = touch
end
--print( "num touches", countTouches())
if( countTouches() == 2 ) then
--calc distance between the touches
a,b = gatherTouches()
av = vec2(a.x, a.y)
bv = vec2(b.x, b.y)
dist = av:dist(bv)
--print("distance between touches", dist)
if( touch.state == BEGAN ) then
--we started a 2-finger touch so mark the distance
initialDistance = dist
--when we stop touching with two fingers, we need to reset ratio and initialDistance
twoFingerTouch = true
elseif( touch.state == MOVING and dist ~= initialDistance ) then
--figure out how much it's changed
if( between(dist, initialDistance*0.5, initialDistance * 2) ) then
ratio = dist / initialDistance
end
end
else
a,b = nil,nil
initialDistance = 0
ratio = 1
end
end
function draw()
background(0, 0, 0, 255)
spriteMode(CENTER)
w,h = spriteSize("SpaceCute:Background")
sprite("SpaceCute:Background",WIDTH/2, HEIGHT/2, w*0.5*ratio, h*0.5*ratio)
for k,touch in pairs(touches) do
-- Use the touch id as the random seed
math.randomseed(touch.id)
-- This ensures the same fill color is used for the same id
fill(math.random(255),math.random(255),math.random(255))
-- Draw ellipse at touch position
ellipse(touch.x, touch.y, 100 * ratio, 100 * ratio)
end
if( a ~= nil and b ~= nil ) then
fill(255,0,0,255)
strokeWidth(1)
line(av.x,av.y, bv.x, bv.y)
end
end
Can anyone see any means of improving this such that the gatherTouches() and countTouches() methods aren't needed?
Comments
Have you tried a forum search, there are a couple of implementations of pinch to zoom on here. One of them I thought worked pretty well. If you add a touch of velocity to it, it can smooth out the motion.
@matkatmusic Here's a version I had that doesn't use a table.
I saw @Herwig's version after following your suggestion and searching for it. I'm at least on the right track, as we both did the same thing (gather the touches, see if there are 2, calc the distance between the two, monitor the change in distance)
Based on the version above I coded my own version which supports pinch to zoom and moving at the same time: https://gist.github.com/dmitrii-eremin/3bfe12835cc4b8a7c6041dde0b654e24
@NeonMercury Works great. Need to add background(0) to the draw function in your example or else you’ll get multiple images as you zoom in/out.
@matkatmusic - neat demo, having a play with it to see where I might apply it. Thanks.