1. Create a new Stack "gesturesEx" with at least three cards.
# 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
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