Pinch / Zoom Confusion and Help Please

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?

views:1459 update:2011/9/29 9:22:17
corona forums © 2003-2011