Ok, so I've got the pinch/zoom code sample working but there are two things I want to accomplish that I suspect are relatively easy but I am just not understanding the code properly (truth be told I hardly understand the pinch/zoom code at all...I get that there is scaling going on and that there is the math to determine the distance between touches etc but I really don't get it).
I need to 1) Be able to start zooming from anywhere on the screen/image/displaygroup. Right now, the code only zooms from the center point of the image, no matter WHERE your fingers are starting. This kind of defeats zoom in my opinion! I bet it's a easy fix but like I said, I just don't understand the code well enough to know where and what to do.
2) I'd like to limit the AMOUNT of zoom (say to 2x). I'm assuming that is done in the scale operation but again, I'm not sure what to do. Right now the code lets you zoom all the way to the pixel level, which is unnecessary.
Thanks for any help.
-Mark
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | <lua> ---------------------------------------------------------------------------------------------- -- code for pinch zoom --------------------------------------------------------------------------------------------- local function calculateDelta( previousTouches, event ) local id,touch = next( previousTouches ) if event.id == id then id,touch = next( previousTouches, id ) assert( id ~= event.id ) end local dx = touch.x - event.x local dy = touch.y - event.y return dx, dy end -- create a table listener object for the bkgd image function localGroup:touch( event ) local result = true local phase = event.phase local previousTouches = self.previousTouches local numTotalTouches = 1 if ( previousTouches ) then -- add in total from previousTouches, subtract one if event is already in the array numTotalTouches = numTotalTouches + self.numPreviousTouches if previousTouches[event.id] then numTotalTouches = numTotalTouches - 1 end end if "began" == phase then -- Very first "began" event if ( not self.isFocus ) then -- Subsequent touch events will target button even if they are outside the stageBounds of button display.getCurrentStage():setFocus( self ) self.isFocus = true previousTouches = {} self.previousTouches = previousTouches self.numPreviousTouches = 0 elseif ( not self.distance ) then local dx,dy if previousTouches and ( numTotalTouches ) >= 2 then dx,dy = calculateDelta( previousTouches, event ) end -- initialize to distance between two touches if ( dx and dy ) then local d = math.sqrt( dx*dx + dy*dy ) if ( d > 0 ) then self.distance = d self.xScaleOriginal = self.xScale self.yScaleOriginal = self.yScale print( "distance = " .. self.distance ) end end end if not previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches + 1 end previousTouches[event.id] = event elseif self.isFocus then if "moved" == phase then if ( self.distance ) then local dx,dy if previousTouches and ( numTotalTouches ) >= 2 then dx,dy = calculateDelta( previousTouches, event ) end if ( dx and dy ) then local newDistance = math.sqrt( dx*dx + dy*dy ) local scale = newDistance / self.distance print( "newDistance(" ..newDistance .. ") / distance(" .. self.distance .. ") = scale(".. scale ..")" ) if ( scale > 0 ) then self.xScale = self.xScaleOriginal * scale self.yScale = self.yScaleOriginal * scale end end end if not previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches + 1 end previousTouches[event.id] = event elseif "ended" == phase or "cancelled" == phase then if previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches - 1 previousTouches[event.id] = nil end if ( #previousTouches > 0 ) then -- must be at least 2 touches remaining to pinch/zoom self.distance = nil else -- previousTouches is empty so no more fingers are touching the screen -- Allow touch events to be sent normally to the objects they "hit" display.getCurrentStage():setFocus( nil ) self.isFocus = false self.distance = nil self.xScaleOriginal = nil self.yScaleOriginal = nil -- reset array self.previousTouches = nil self.numPreviousTouches = nil end end end return result end <blockcode> |
I'm trying to figure out how to limit the zoom here too. Any luck?