#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Pinch Zoom

Posts: 212

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,a
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?

• Posts: 2,020

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.

• Posts: 9,441

@matkatmusic Here's a version I had that doesn't use a table.

``````function setup()
t1,t2=vec3(0,0,0),vec3(0,0,0)
scale=img.width
end

function draw()
background(40, 40, 50)
sprite(img,WIDTH/2,HEIGHT/2,scale)
end

function touched(t)
if t.state==BEGAN then
hdist=0
if t1.z==0 then
t1=vec3(t.x,t.y,t.id)
elseif t2.z==0 then
t2=vec3(t.x,t.y,t.id)
end
end
if t.state==MOVING then
if t1.z==t.id then
t1=vec3(t.x,t.y,t.id)
elseif t2.z==t.id then
t2=vec3(t.x,t.y,t.id)
end
if t1.z~=0 and t2.z~=0 then
dist=vec2(t1.x,t1.y):dist(vec2(t2.x,t2.y))
if dist-hdist>0 then
scale=scale*1.02
else
scale=scale*.98
end
hdist=dist
end
end
if t.state==ENDED then
if t1.z==t.id then
t1=vec3(0,0,0)
elseif t2.z==t.id then
t2=vec3(0,0,0)
end
end
end
``````
• Posts: 212

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)

• Posts: 1

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

• Posts: 9,441

@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.

• Posts: 2,364

@matkatmusic - neat demo, having a play with it to see where I might apply it. Thanks.