iOS - PDF Interaction & iBooks

Getting into LiveCode for iOS? Ask your questions here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

DougN
Posts: 20
Joined: Wed Mar 04, 2009 4:09 am

Re: iOS - PDF Interaction & iBooks

Post by DougN » Thu Jun 16, 2011 7:11 pm

put "false" into kickSelf
That's hilarious (and probably healthy, too). I think I may need to adopt this in all my stack scripts.

Doug

Tester2
Posts: 102
Joined: Wed May 18, 2011 7:02 pm

Re: iOS - PDF Interaction & iBooks

Post by Tester2 » Thu Jul 07, 2011 4:22 pm

My fellow LiveCoders....

I have been up the mountain and received a gift from the gods...a stack that had the code for how to pinch and zoom on an image!!! :D

The forum won't let me upload the stack...so I'll post the long code below.

I thought it would be rude not to share....enjoy!

-Tester2

----------------------------------

Code: Select all

[
local sTouches   -- an array storing the location of all the current touches (user's fingers) on the screen
local sDist      -- if we have two tocuhes, this stores the last distance between them
local sWHRatio   -- the width height (aspect) ratio of the current image

constant kPinchScaleRatio = 0.4  -- 1 unit of pinch movement results in a kPinchScaleRatio percentage image scaling

on preOpenStack
   iphoneUseDeviceResolution true
end preOpenStack

on openCard
   
   -- cache the width height ratio of the image of this current card
   -- this is used when making sure the image fits within the current card (see validateRect)
   --
   put the effective width of image "comic" / the effective height of image "comic" into sWHRatio
   
end openCard

on touchMove pId, pX, pY
   
   if sTouches[pId] is empty then
      
      -- this is the first time we have touched, store the location of this touch
      --
      put (pX, pY) into sTouches[pId]
      
      -- if we already have another touch, then cache the distance between the two touches
      -- this means the user has placed a second finger on the screen and may be about to start a pinch motion
      -- we store the current distance between the users fingers so that we know how much the user has moved if they pinch
      --
      if the number of elements in sTouches is 2 then
         put distBetweenPts(sTouches[line 1 of the keys of sTouches], sTouches[line 2 of the keys of sTouches]) into sDist
      end if
      
   else if the number of elements in sTouches is 2 then
      
      -- store the location of this touch for future reference
      --
      put (pX, pY) into sTouches[pId]
      
      -- we have two touches, this means the user has pinched and wants to resize the image
      -- work out the distance bewtween the touches (user's fingers)
      --
      local tDist
      put distBetweenPts(sTouches[line 1 of the keys of sTouches], sTouches[line 2 of the keys of sTouches]) into tDist  
      
      -- we only want to scale the image if the distance between the two touches has changed
      -- i.e. the user has moved one or both of their fingers
      --
      if tDist is not sDist then
         
         -- work out by how much we want to scale the image based on the distance moved / pinched
         --
         local tScale
         put 1 + (tDist - sDist) / 100 * kPinchScaleRatio into tScale
         
         -- scale the image by working out its new rect
         -- the new width and height are simply calculated by multiplying by the scale
         --
         local tWidth, tHeight, tLeft, tTop
         put round(the width of image "comic" * tScale) into tWidth
         put round(the height of image "comic" * tScale) into tHeight
         
         -- the top and left are a bit trickier - we want to zoom in/out on a fixed point in the image
         -- i.e. we want the point of the image which is currently at the center of the sceen 
         -- to remain there during the scaling operation
         -- to maintain this central point we first work out the current distance between the left (and top) of the image
         -- and the center of the screen (the loc of the current card)
         -- this distance will be scaled up/down in the same way as the width and height of the image
         -- we then used this new scaled distance to calculate the new left (and top) of the image
         --
         put round(item 1 of the loc of this card + (the left of image "comic" - item 1 of the loc of this card) * tScale) into tLeft
         put round(item 2 of the loc of this card + (the top of image "comic" - item 2 of the loc of this card) * tScale) into tTop
         
         -- set the new rect of the image based on the newly calculated values
         -- making sure the rect is within the current card by calling validateRect
         -- we set the rect  rather than the width, height, left, top, loc etc as this only scales the image once
         --
         set the rect of image "comic" to validateRect((tLeft, tTop, tLeft + tWidth, tTop + tHeight), sWHRatio)
         
         -- store the new distance between the touches
         --
         put tDist into sDist
         
      end if     
      
   else
      
      -- if the user is not pinching/scaling the image then we just want to move the image
      -- calculate by how much we want to move the image based on how far the user has moved thier finger
      -- this is done by calculating the difference between the current touch x and y coords from the last
      --
      local tXOffset, tYOffset
      put pX - item 1 of sTouches[pId] into tXOffset
      put pY - item 2 of sTouches[pId] into tYOffset
      
      -- set the new position of the image remebering to make sure it is within the current card
      --
      set the rect of image "comic" to validateRect((the left of image "comic" + tXOffset, the top of image "comic" + tYOffset, the right of image "comic" + tXOffset, the bottom of image "comic" + tYOffset), sWHRatio)
      
      -- store the location of the touch so we can calculate the distance on the next move or pinch
      --
      put (pX, pY) into sTouches[pId]
      
   end if
   
end touchMove

-- on touch end and touch release remove the touch location data from our array of touches 

on touchEnd pId
   delete variable sTouches[pId]
end touchEnd

on touchRelease pId
   delete variable sTouches[pId]
end touchRelease

-- Returns the distance between two coordinates using Pythagoras theorem
--
private function distBetweenPts pPt1, pPt2
   return sqrt((item 1 of pPt1 - item 1 of pPt2) ^ 2 + (item 2 of pPt1 - item 2 of pPt2) ^ 2)
end distBetweenPts

-- Make sure the rect passed is not outwith the bounds of the current card
-- Returns a new rect that fits within the bounds of the current card
--
private function validateRect pRect, pWHRatio
   
   -- if the width of the rect is less than the width of this card
   -- then scale the rect so that it's equal to the width of the card
   -- as we are altering the width of the rect, we want to maintain its aspect ratio
   -- so also set the height based of the width height ratio passed
   --
   if (item 3 of pRect - item 1 of pRect) < the width of this card then
      put item 1 of pRect + the width of this stack into item 3 of pRect
      put item 2 of pRect + the width of this stack div pWHRatio into item 4 of pRect
   end if 
   
   -- do the same if the rect is taller than the current card
   -- set the rect to be the same height as the stack and scale the width appropriately
   --
   if (item 4 of pRect - item 2 of pRect) < the height of this card then
      put item 2 of pRect + the height of this card into item 4 of pRect
      put item 1 of pRect + the height of this card * pWHRatio into item 3 of pRect
   end if 
   
   -- make sure that there is no space around the outside of the rect
   -- for example, if there is space bewteen the left hand side of this card and the rect
   -- (the left of the rect > 0), then snap the left of the rect to the left hand side of this card
   -- remembering to adjust the right of the rect so that the width is preserved
   --  
   if item 1 of pRect > 0 then
      put (0, item 2 of pRect, item 3 of pRect - item 1 of pRect, item 4 of pRect) into pRect 
   end if
   if item 2 of pRect > 0 then
      put (item 1 of pRect, 0, item 3 of pRect, item 4 of pRect - item 2 of pRect) into pRect 
   end if
   if item 3 of pRect < the width of this card then
      put (the width of this card - (item 3 of pRect - item 1 of pRect), item 2 of pRect, the width of this card, item 4 of pRect) into pRect 
   end if
   if item 4 of pRect < the height of this card then 
      put (item 1 of pRect, the height of this card - (item 4 of pRect - item 2 of pRect) , item 3 of pRect, the height of this card) into pRect 
   end if 
   
   -- return the adjusted rect
   --
   return pRect
   
end validateRect
]

CALL-151
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 206
Joined: Wed Oct 20, 2010 11:00 am

Re: iOS - PDF Interaction & iBooks

Post by CALL-151 » Fri Jul 08, 2011 1:28 pm

DougN wrote:
put "false" into kickSelf
That's hilarious (and probably healthy, too). I think I may need to adopt this in all my stack scripts.

Doug
Happy to see that one other person in the universe shares my stupid sense of geek humor.

Post Reply