1. Create a new Stack "gesturesEx" with at least three cards.
Stack script:
# Everything here you have seen before
# except the acceleratedRendering property
on preopenstack
set the acceleratedRendering of this stack to true
set the fullscreenmode of me to "showAll"
if mob() then
mobileSetAllowedOrientations "portrait,portrait upside down,landscape left,landscape right"
end if
end preopenstack
function dev
return the environment is "development"
end dev
function mob
return the environment is "mobile"
end mob
2. On each card, a background group consisting of these objects
Group script:
local sTouchArray, sStartH, sObjWidth, sObjHeight, sDoubleTouchIDs
on preOpenCard
set the layerMode of image "pict" to "dynamic"
delete variable sTouchArray
put the imglist of me into tImgs
put the number of this cd into tNum
put line tNum of tImgs & ".png" into tImgName
set the filename of img "Pict" to (specialFolderPath("resources") & "/" & tImgName)
resetImg
setCardLayout the width of this stack, the height of this stack
end preOpenCard
on closeCard
delete variable sTouchArray
end closeCard
on resetImg
set the width of img "pict" to the formattedWidth of img "pict"
set the height of img "pict" to the formattedHeight of img "pict"
set the loc of img pict to the loc of this card
end resetImg
3. Add screen resizing handlers to the group script to adapt to device screen size and orientation.
on resizeStack pNewWidth,pNewHeight
setCardLayout pNewWidth,pNewHeight
end resizeStack
on setCardLayout pWdth, pHgt
resetImg
# position prev and next buttons
set the bottomLeft of btn "prev" to 4,pHgt - 4
set the bottomRight of btn "next" to pWdth - 4, the bottom of btn "prev"
# position title fld
set the width of fld "title" to pWdth
set the topLeft of fld "title" to 0,0
# position reset button
if pWdth < pHgt then # portrait
set the bottom of btn "reset" to the bottom of btn "prev"
set the loc of btn "reset" to pWdth div 2, item 2 of the loc of btn "reset"
else # landscape
set the right of btn "reset" to pWdth - 4
set the loc of btn "reset" to item 1 of the loc of btn "reset", pHgt div 2
end if
end setCardLayout
4. Add swipe motion scripting for going between cards
Add to group script:
local sStartH
on touchStart pId
put the mouseH into sStartH
end touchStart
on touchEnd pId
if abs(the mouseH - sStartH) > 50 then
if the mouseH < sStartH then
goNext
else
goPrev
end if
end if
end touchEnd
on goNext
lock screen for visual effect --in rect (the rect of img "pict")
go next card
unlock screen with visual push left very fast
end goNext
on goPrev
lock screen for visual effect --in rect (the rect of img "pict")
go prev card
unlock screen with visual effect push right very fast
end goPrev
5. Show multi-touch tutorial at http://lessons.runrev.com/s/lessons/m/4069/l/11509-how-do-i-implement-a-multi-touch-pinch-motion
See sample stack from this tutorial, demo in simulator
Explain what's happening in the card script of the sample stack.
Explain simple trig for figuring out distance between start and end touch.
6. Adapt this script to act on the img "pict" instead.
In our stack we need to put the "pinch" scripting in the group script rather than the card script as in the tutorial.
Adapting it to work with our image is fairly straightforward: - set the resizeQuality of the image to "good" - replace all of the references to graphic "square" with image "pict"
The tricky part is making sure that double touches aren't triggering the single-touch swipe scripting. The group script will require these local variables:
local sTouchArray, sStartH, sObjWidth, sObjHeight, sDoubleTouchIDs
The touchStart and touchEnd handlers have to be modified to handle pinch gestures:
on touchStart pId
put the width of img "pict" into sObjWidth
put the height of img "pict" into sObjHeight
put the mouseH into sStartH
end touchStart
# clean things up after the touch
on touchEnd pId
if pId is not among the lines of sDoubleTouchIDs then
if abs(the mouseH - sStartH) > 50 then
if the mouseH < sStartH then
goNext
else
goPrev
end if
end if
end if
delete variable sTouchArray[pId]
# remove the touch just ended from the double touch list
filter sDoubleTouchIDs without pId
end touchEnd
Finally, these handlers do the actual resizing of the image:
on touchMove pId, pX, pY
# If this is the first touchMove message for a given touch (see pID), store the startpoint of the touch
if sTouchArray[pId]["startloc"] is empty then
put (pX,pY) into sTouchArray[pId]["startloc"]
end if
# Now store the current position of the touch
put (pX,pY) into sTouchArray[pId]["currentloc"]
# 2 touches on the screen = a pinch gesture
if the number of lines of the keys of sTouchArray is 2 then
# save a list of the IDs involved in the double touch
# this lets us check for a single or double touch on touchEnd
put the keys of sTouchArray into sDoubleTouchIDs
# get the current loc of the two touches
# remember, the keys are the touch IDs
put line 1 of the keys of sTouchArray into tPointOne
put line 2 of the keys of sTouchArray into tPointTwo
# now get the start positions of the two touches
# by comparing the start and current positions of the two touches
# we can tell if they are getting closer or farther from each other
put sTouchArray[tPointOne]["startloc"] into tStartLoc1
put sTouchArray[tPointTwo]["startloc"] into tStartLoc2
put sTouchArray[tPointOne]["currentloc"] into tCurrLoc1
put sTouchArray[tPointTwo]["currentloc"] into tCurrLoc2
if tStartLoc1 is not empty AND tStartLoc2 is not empty then
# Calculate two distances:
# - distance between the two start locations
# - distance between the two current locations
put resizeDistance(tStartLoc1,tStartLoc2) into tStartDist
put resizeDistance(tCurrLoc1,tCurrLoc2) into tCurrDist
resizeImg tStartDist,tCurrDist
end if
end if
end touchMove
# calculate the distance between two points, using some geometry
# remember the Pythagorean theorem for the length of the hypotenuse
# of a right triangle: a2 + b2 = c2
function resizeDistance pLoc1, pLoc2
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^2) + (dx^2)) into tDistance
return tDistance
end resizeDistance
# calculate how to resize the image
on resizeImg pStartDist,pNewDist
put pNewDist / pStartDist into tRatio
put the loc of img "pict" of me into tCenterPt
set the width of img "pict" of me to round(sObjWidth * tRatio)
set the height of img "pict" of me to round(sObjHeight * tRatio)
set the loc of img "pict" of me to tCenterPt
unlock screen
end resizeImg
The final working stack is on the server at http://dight310.byu.edu/lesson_materials/12-Motion_and_gestures/. It is named GesturesEx.livecode