How do I implement a multi-touch pinch motion?
The pinch motion that you find in many iPhone apps is known as a 'gesture'. Apple don't provide support for specific gestures such as pinch leaving us as developers to implement them ourselves from touch messages. This does mean we have to do a little math but we'll work through that together in this lesson.
The pinch gesture is often used to shrink and grow items like photos. In this lesson we'll use the pinch gesture to scale a plain graphic.
* The image scaling algorithms in LiveCode have not been optimized for the iPhone yet meaning that dynamic image scaling is quite slow on the device. So in this example we are scaling a graphic which is very fast.
The stack used in this lesson can be found here: https://tinyurl.com/y7jn6yvw
Setup our stack
1) Create a new stack, name it and save it
2) Stop the stack from being resized
3) Set the width and height of the stack to 320 x 460
Add the graphic we're going to resize together
1) Create a square graphic
2) Set its name to 'square'
3) Go to the colors & patterns inspector and set the 'backgroundColor' to one you like
Basic Multi-touch Message
We're going to leave the interface for a moment and look at the basic messages we receive from Rev when touches start, end and move.
on touchStart pTouchId # Sent each time a new touch is started end touchStart on touchEnd pTouchId # Sent each time a touch ends end touchEnd on touchMove pTouchId, pX, pY # Sent when any touch moves end touchMove
If a user places two fingers on the device, two touch starts messages will be sent to your stack. You will also be sent a touch ID so you can tell they are different.
The Final Script
Copy this script to the card or stack.
1) Looks for two touches
2) Calculates the distance between the two touches to work out if they are getting closer or further away
3) Scales the image according to the distance of the two touches,
local sTouchArray, sFRAMEWIDTH, sFRAMEHEIGHT on touchStart pId # Store the staring width and height of the graphic put the width of graphic "square" into sFRAMEWIDTH put the height of graphic "square" into sFRAMEHEIGHT end touchStart on touchEnd pId # When the touch end remove the ID from the array tracking all our touches delete variable sTouchArray[pId] end touchEnd on touchMove pId, pX, pY # First thing we want to do is store the start point of the touch # If this is the first move message for a given touch lets store # it in our array if sTouchArray[pId]["startloc"] is empty then put (pX & comma & pY) into sTouchArray[pId]["startloc"] end if # We want to store the current position of the touch put (pX & comma & pY) into sTouchArray[pId]["currentloc"] # If we know there are two touches on the screen we know that the # user is performing a pinch if the number of lines of the keys of sTouchArray is 2 then # First lets get the current location of the two touches put line 1 of the keys of sTouchArray into tPointOne put line 2 of the keys of sTouchArray into tPointTwo # Get the start positions of the two touches. If the know the start # and current positions of the two touches who can calculate if the # touches are getting closer of further from each other put sTouchArray[tPointOne]["startloc"] into tStartLoc1 put sTouchArray[tPointTwo]["startloc"] into tStartLoc2 if tStartLoc1 is not empty and tStartLoc2 is not empty then # Calculate the two distances. Distance at the start between two touches and the # distance between the two touches now put resizeDistance(tStartLoc1, tStartLoc2) into tStartDistance put resizeDistance(sTouchArray[tPointOne]["currentloc"], sTouchArray[tPointTwo]["currentloc"]) into tCurrentDistance # Now that we have the data we can resize the graphic resizeGraphic tStartDistance, tCurrentDistance end if end if end touchMove function resizeDistance pLoc1, pLoc2 # Using basic trig we calculate the distance between two points put item 2 of pLoc1 - item 2 of pLoc2 into dy put item 1 of pLoc1 - item 1 of pLoc2 into dx put sqrt((dy*dy) + (dx*dx)) into tDistance return tDistance end resizeDistance on resizeGraphic pStartDistance, pNewDistance # Work out the percentage change between the old and new image put round((pNewDistance / pStartDistance) * 100) into tPercentage # Store the original location of the graphic put the loc of graphic "square" into tLoc # Calculate the new width and height set the width of graphic "square" to round(sFRAMEWIDTH * (tPercentage / 100)) set the height of graphic "square" to round(sFRAMEHEIGHT * (tPercentage / 100)) set the loc of graphic "square" to tLoc unlock screen end resizeGraphic
Test in the Simulator
1) Load the stack into the simulator
2) Hold the 'alt' key to bring up the multi-touch pointers (two grey circles in the screenshots above)
3) Click and drag to simulate touches moving apart / closer. The square will shrink and grow accordingly.