How do you limit pinch zoom?

I'm working with the sample code - http://developer.anscamobile.com/content/pinch-zoom-gesture and can't figure out where you'd set it up to limit the minimum/maximum scale of the background. Here's the code from the sample:

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
-- activate multitouch
system.activate( "multitouch" )
 
-- add bkgd image to screen
local background = display.newImage( "aquariumbackgroundIPhone.jpg", 0, 0 )
 
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 background: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
 
-- Determine if running on Corona Simulator
--
local isSimulator = "simulator" == system.getInfo("environment")
 
-- Multitouch Events not supported on Simulator
--
if isSimulator then
        msg = display.newText( "Multitouch not supported on Simulator!", 0, 20, "Verdana-Bold", 14 )
        msg.x = display.contentWidth/2          -- center title
        msg.y = display.contentHeight/2         -- center title
        msg:setTextColor( 255,255,0 )
end
 
-- register table listener
background:addEventListener( "touch", background )

I've got the same question. Any advice?

I would just like to know when a pinch and un-pinch occurs. I do not need to know the values

The sample code looks overly complexed, can someone show me how to just detect a pinch and un-pinch. I will be zooming and unzoom to a fixed value.

Keep in mind that the pinch/zoom is completely fluid, meaning the user can go either way and switch direction anytime.

In lines 55-60, the original distance between the first and second touch is discovered, but the magic happens in lines 79-86 where it changes the scale based on the change in the distance.

When it's calculating the distance between the two points and assigning it to newDistance, and if it's less than the original distance stored in self.distance, it's a pinch. If it's greater, it's a zoom.

I agree it can look a little convoluted, but multitouch is much more complicated than detecting a single touch, since you have to track multiple fingers, and if one lets go or one gets added, the program has to know how to handle them individually.

Has anyone gotten this to work, iDesperately need a solution, i've basically tried everything I could think of, so if anyone can point me in the direction or provide code it'd be greatly appreciated.

Hi,
I've made a pinch zoom module easier then in the pinch zoom sample.
I think it may help you, you only have to set an

1
2
3
if image.contentWidth < yourMaximumWidth then
--the zoom in code
end

Go to this part of the pinch-zoom-gesture code sample: starting from line 82

82 if ( scale > 0 ) then
83 self.xScale = self.xScaleOriginal * scale
84 self.yScale = self.yScaleOriginal * scale
85 end

and make the following changes:

if ( scale > 0) then

if ( ( self.xScaleOriginal * scale ) > 0.5 and ( self.xScaleOriginal * scale ) <2.0 ) then
self.xScale = self.xScaleOriginal * scale
self.yScale = self.yScaleOriginal * scale

end

end

here the limits are >0.5 and <2.0

meaning that the ZOOM OUT stop when the image (or stage or whatever you are zooming on) become scaled at 50% of its original size, and the ZOOM IN also stop when the image become scaled at 200% of its original size. Of course you can change these limits.

views:1893 update:2012/1/2 12:52:55
corona forums © 2003-2011