In this post, we’ll look at a simple pinch and zoom class, as an introduction to handling touches – and get a little more practice with classes. This one is quite short.

You should also look at this later post, which explains touch more fully.

We’ll draw an image on the screen, and zoom it in or out as the user pinches or zooms with two fingers. We’ll calculate the zoom very simply, as the ratio of the distance between the fingers now, to the distance the last time we measured it. So if the fingers are 100 apart now, and they were 80 before, we’ll apply a zoom of 100/80 = 125%.

Codea tells you about touches using this function in Main

```function touched(touch)
-- your code here
end```

Every single touch calls this function (two fingers means it is called twice), and it keeps getting called as you hold your finger(s) down, until you let go.

Codea provides the touch item when it calls touched, and this has lots of useful information about the touch (see the built in help for full details – press the little square at top left of the main Codea screen and find your way from there).

Probably the most important information is the state property, which has three values – BEGAN, for the start of the touch, MOVING, while the touch continues, and ENDED. The BEGAN and ENDED states will occur exactly once for each touch, but the MOVING state could occur dozens of times, depending on the length of the touch.

There is also an x and y property to tell you where the touch happened. This example shows all of these in action. It will print a message when each touch ends.

```function touched(touch)
if touch.state==ENDED then
print('You touched',touch.x,touch.y)
end
end```

These items are all we will need for pinch and zoom. The problem, though, is that the touched function is called separately for each finger touch. How will we identify a two finger touch, as opposed to a three or four finger touch?

What I’ve done is to use a table “tb” to store a couple of details about each touch, and in the draw function, we’ll count the number of touches in the table. If there are two, we’ll calculate the distance between the fingers and compare it with the previous value, which we’ve stored. We can then ratio the two distances to calculate zoom, which is then used to draw the sprite.

For neatness, I’m going to put my pinch code into a class, like so (it’s mainly comments)

```pinch=class()

function pinch:init()
self.tb={}. -- this table will hold touch info
self.zoom=1 --set the initial zoom
end

--this function doesn't call itself. Only the touched
--function in Main does that, but we will get that
--function to call this one, and pass the touch info across
function pinch:touched(touch)
--when touch ends, clear table and set distances to nil
if touch.state==ENDED then self.tb={} self.d1=nil self.d2=nil
--if we are touching, add touch to tb, store x and y
else table.insert(self.tb,{x=touch.x,y=touch.y}) end
end

--draw in Main will call this function, to see if we
--need to pinch/zoom
function pinch:processTouches()
if #self.tb==2 then -- continue if we had two touches
--set the two vectors for the two fingers
local v1=vec2(self.tb[1].x,self.tb[1].y),
local v2=vec2(self.tb[2].x,self.tb[2].y)
self.d1=v1:dist(v2). -- calculate the distance between
end
--if we've got a previous measurement, check if its
--changed and set the zoom
if self.d2~=nil then self.zoom=self.zoom*self.d1/self.d2 end
--store the current distance and clear the array
self.d2=self.d1  self.tb={}
end```

The code below illustrates how to use the class. It only takes about 4 lines of code. As you get to use classes more and more, you will increasingly rely on those classes to handle touches and drawing, rather than Main, so it’s important to know how to do it.

```function setup()
p=pinch() --initialise pinch
end

function draw()
background(0)
p:processTouches(). --process touches
sprite(img,WIDTH/2,HEIGHT/2,500*p.zoom) --note zoom
end

function touched(touch)
p:touched(touch) --pass the touch data to p
end```

And the full code is here or here.

From → animation

1. Ken Duerden permalink

Thanks for this lesson. I had been having trouble with touches and in a game I am developing to learn Codea I was getting double inputs whenever I touched the screen. Proper use of the touch.state ENDED has sorted this for me. Brilliant !

What does “~=” symbol mean?
It can’t be almost equal it, can it?

• Saurabh, it means not equal to – but you really need to do some reading.

Have a look at the Lua documentation (I think I gave a link to it in about post 4), and try to learn the basics of the language. You can’t learn everything from my posts – they are intended only to explain the difficult parts of the language, and you need to read up on the easy stuff by yourself.

I didn’t understand one thing. where do you calculate self.d2 before using it in processTouches to set the zoom

• Look at the last line of processTouches