Pinch and Zoom - Livecode lesson modification

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
okk
Posts: 176
Joined: Wed Feb 04, 2015 11:37 am

Pinch and Zoom - Livecode lesson modification

Post by okk » Wed Jun 02, 2021 12:53 pm

Hi,

the livecode lesson on pinching https://lessons.livecode.com/m/4069/l/1 ... nch-motion is often referenced but it is not producing a superuseful zoom, since the zoom focusses on the centre of the image and not on the area that is pinched. Below is my quick and dirty mod that produces a pinch & zoom and drag behaviour that I would expect on mobile. Feel free to make it more beautiful. This script doesn't do rotation, so I did not post it to the recent thread on pinch and rotate. If a moderator feels this topic should be merged, please do. Thanks to the original author of the lesson, it was very useful as a base. Best. Oliver

Code: Select all

local sTouchArray, sFRAMEWIDTH, sFRAMEHEIGHT
local tempimagex, tempimagey, focusx, focusy, pinchflag

on touchStart pId, pX, pY
   put the width of image "ballotimage" into sFRAMEWIDTH
   put the height of image "ballotimage" into sFRAMEHEIGHT
   put item 1 of the loc of image "ballotimage" into tempimagex
   put item 2 of the loc of image "ballotimage" into tempimagey
end touchStart

on touchEnd pId
   if the number of lines of the keys of sTouchArray is 1 then
      put false into pinchflag
   end if
   delete variable sTouchArray[pId]
end touchEnd

on touchMove pId, pX, pY
   
   if sTouchArray[pId]["startloc"] is empty then
      put (pX & comma & pY) into sTouchArray[pId]["startloc"]
   end if
   
   put (pX & comma & pY) into sTouchArray[pId]["currentloc"]
   
   
   -- sxcript if user wants to move image around:
   if the number of lines of the keys of sTouchArray is 1 then
      --First lets get the data out of the array
      put line 1 of the keys of sTouchArray into tPointOne
      put sTouchArray[tPointOne]["startloc"] into tStartLoc
      if tStartLoc1 is not empty  then
         put item 1 of tStartLoc into tempstartx
         put item 2 of tStartLoc into tempstarty
         put tempstartx-pX into tempdiffx
         put tempstarty-pY into tempdiffy
         
         put tempimagex-tempdiffx into tempimagecurrentx
         put tempimagey-tempdiffy into tempimagecurrenty
         if pinchflag is not true then
            set the loc of image "ballotimage" to tempimagecurrentx, tempimagecurrenty
         end if
      end if
   end if
   
   -- script when user want to pinch and zoom:
   if the number of lines of the keys of sTouchArray is 2 then
      # First lets get the data out of the array
      put line 1 of the keys of sTouchArray into tPointOne
      put line 2 of the keys of sTouchArray into tPointTwo
      
      # First lets calculate the size of the picture base on the distance 
      # between the two touch points
      put sTouchArray[tPointOne]["startloc"] into tStartLoc1
      put sTouchArray[tPointTwo]["startloc"] into tStartLoc2
      if tStartLoc1 is not empty and tStartLoc2 is not empty then
         put true into pinchflag -- to avoid a jump in location when 1 finger is removed
         
         -- calculate the focus point of the zoom, it is located between the two starting touchpoints
         put item 1 of tStartLoc1 into focusx1
         put item 2 of tStartLoc1 into focusy1
         
         put item 1 of tStartLoc2 into focusx2
         put item 2 of tStartLoc2 into focusy2
         
         put focusx1 + round ((focusx2-focusx1)/2) into focusx
         put focusy1 + round ((focusy2-focusy1)/2) into focusy
         
         put resizeDistance(tStartLoc1, tStartLoc2) into tStartDistance
         put resizeDistance(sTouchArray[tPointOne]["currentloc"], sTouchArray[tPointTwo]["currentloc"]) into tCurrentDistance
         resizeGraphic tStartDistance, tCurrentDistance
      end if
   end if
end touchMove

function resizeDistance pLoc1, pLoc2
   local dy, dx, tDistance
   
   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*dy) + (dx*dx)) into tDistance
   
   return tDistance
end resizeDistance 

on resizeGraphic pStartDistance, pNewDistance
   lock screen
   # Work out the percentage change between the old and new image
   put round((pNewDistance / pStartDistance) * 100) into tPercentage
   
   # Calculate the new width and height
   set the width of image "ballotimage"  to round(sFRAMEWIDTH * (tPercentage / 100))
   set the height of image "ballotimage" to round(sFRAMEHEIGHT * (tPercentage / 100))
   
   -- first scale the coordinates of the focus point
   put tempimagex + round((focusx-tempimagex) * (tPercentage / 100)) into focusxnew
   put tempimagey + round((focusy-tempimagey) * (tPercentage / 100)) into focusynew
   
   -- getting the difference between original and scaled focuspoint
   put focusx - focusxnew into focusxdiff
   put focusy - focusynew into focusydiff
   
   -- calculate the new location of the graphic
   put tempimagex + focusxdiff into locxnew
   put tempimagey + focusydiff into locynew
   set the loc of image "ballotimage"  to  locxnew,locynew
   unlock screen
end resizeGraphic



JereMiami
Posts: 119
Joined: Mon Nov 03, 2014 12:17 am

Re: Pinch and Zoom - Livecode lesson modification

Post by JereMiami » Tue Oct 11, 2022 9:05 pm

This works and it is very awesome! Thanks for sharing. Any chance you got code to also resize any objects overlaying the image along with it?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9801
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Pinch and Zoom - Livecode lesson modification

Post by FourthWorld » Tue Oct 11, 2022 11:25 pm

Thank you for that update. You might consider sending your improved code to the author of that page or to support AT livecode.com so it can replace the weaker code that's there now. The centering issue with the older code has been noted before, and they really do need to update the public example.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

JereMiami
Posts: 119
Joined: Mon Nov 03, 2014 12:17 am

Re: Pinch and Zoom - Livecode lesson modification

Post by JereMiami » Thu Oct 13, 2022 11:52 am

I've attached my code which is based on the above code (which, the above code is truly excellent). In the below code, the image is a pdf document converted to a jpeg, which allows you to place fields onto the form and/or place an overlaying image that functions as a signature block (e.g., svg image). I did not try the signature widget, but that may work too (although the signture in this example is taken from the signature widget on another card). Think Docuware or Docusign, or your typical generice mobile app for signing a mortgage or lease agreement.

Note that I set the vis of any overlaying object to false while the user is performing any touch action because I just do not think that it looks good while the user resizes the underlying image. The textSize is also resized while the vis is set to false and the user is resizing the underlying image. On touchEnd, the vis is set to true. All overlaying objects use repeat and a datagrid for their resize and textSize.

Also note that all of this code goes into the underlying image (the pdf form converted to a jpg). The fields are filled in with preOpenCard and the signature is added with a prompt to the user (e.g. "Accept and Sign?").

Code: Select all

local sTouchArray, sFRAMEWIDTH, sFRAMEHEIGHT, sFIELDWIDTH, sFIELDHEIGHT, sNEWFIELDHEIGHT
local tempimagex, tempimagey, focusx, focusy, pinchflag, tempfieldx, tempfieldy,tStartDistance, tCurrentDistance, tData, tMax

on touchStart pId, pX, pY
   if the environment is "mobile" then
      put the dgData of grp "dg" into tData
      put the dgNumberOfLines of grp "dg" into tMax
      repeat with l = 1 to tMax
         if tData[l]["name"] is "signature" then
            set the vis of img tData[l]["name"] to false
         else
            
            set the vis of fld tData[l]["name"] to false
         end if
      end repeat
      
      put the width of img "document" into sFRAMEWIDTH
      repeat with l = 1 to tMax
         if tData[l]["name"] is "signature" then
            put the width of img tData[l]["name"] into tData[l]["sFIELDWIDTH"]
         else
            put the width of fld tData[l]["name"] into tData[l]["sFIELDWIDTH"]
         end if
      end repeat
      
      put the height of img "document" into sFRAMEHEIGHT
      repeat with l = 1 to tMax
         if tData[l]["name"] is "signature" then
            put the height of img tData[l]["name"] into tData[l]["sFIELDHEIGHT"]
         else
            put the height of fld tData[l]["name"] into tData[l]["sFIELDHEIGHT"]
         end if
      end repeat
      
      put item 1 of the loc of img "document" into tempimagex
      repeat with l = 1 to tMax
         if tData[l]["name"] is "signature" then
            put item 1 of the loc of img tData[l]["name"] into tData[l]["tempfieldx"]
         else
            put item 1 of the loc of fld tData[l]["name"] into tData[l]["tempfieldx"]
         end if
      end repeat
      
      put item 2 of the loc of img "document" into tempimagey
      repeat with l = 1 to tMax
         if tData[l]["name"] is "signature" then
            put item 2 of the loc of img tData[l]["name"] into tData[l]["tempfieldy"]
         else
            put item 2 of the loc of fld tData[l]["name"] into tData[l]["tempfieldy"]
         end if
      end repeat
   end if
end touchStart

on touchEnd pId
   repeat with l = 1 to tMax
      if tData[l]["name"] is "signature" then
         set the vis of img tData[l]["name"] to true
      else
         set the vis of fld tData[l]["name"] to true
      end if
   end repeat
   
   if the environment is "mobile" then
      if the number of lines of the keys of sTouchArray is 1 then
         put false into pinchflag
      end if
      delete variable sTouchArray[pId]
   end if
   set the dgData of grp "dg" to tData
end touchEnd

on touchMove pId, pX, pY
   if the environment is "mobile" then
      if sTouchArray[pId]["startloc"] is empty then
         put (pX & comma & pY) into sTouchArray[pId]["startloc"]
      end if
      
      put (pX & comma & pY) into sTouchArray[pId]["currentloc"]
      
      
      -- script if user wants to move image around:
      if the number of lines of the keys of sTouchArray is 1 then
         --First lets get the data out of the array
         put line 1 of the keys of sTouchArray into tPointOne
         put sTouchArray[tPointOne]["startloc"] into tStartLoc
         if tStartLoc1 is not empty  then
            put item 1 of tStartLoc into tempstartx
            put item 2 of tStartLoc into tempstarty
            put tempstartx-pX into tempdiffx
            put tempstarty-pY into tempdiffy
            
            put tempimagex-tempdiffx into tempimagecurrentx
            repeat with l = 1 to tMax
               put tData[l]["tempfieldx"] - tempdiffx into tData[l]["tempfieldcurrentx"]
            end repeat
            
            
            put tempimagey-tempdiffy into tempimagecurrenty
            repeat with l = 1 to tMax
               put tData[l]["tempfieldy"] - tempdiffy into tData[l]["tempfieldcurrenty"]
            end repeat
            
            if pinchflag is not true then
               set the loc of img "document" to tempimagecurrentx, tempimagecurrenty
               repeat with l = 1 to tMax
                  if tData[l]["name"] is "signature" then
                     set the loc of img tData[l]["name"] to tData[l]["tempfieldcurrentx"], tData[l]["tempfieldcurrenty"]
                  else
                     set the loc of fld tData[l]["name"] to tData[l]["tempfieldcurrentx"], tData[l]["tempfieldcurrenty"]
                  end if
               end repeat
            end if
         end if
      end if
      
      -- script when user want to pinch and zoom:
      if the number of lines of the keys of sTouchArray is 2 then
         # First lets get the data out of the array
         put line 1 of the keys of sTouchArray into tPointOne
         put line 2 of the keys of sTouchArray into tPointTwo
         
         # First lets calculate the size of the picture base on the distance 
         # between the two touch points
         put sTouchArray[tPointOne]["startloc"] into tStartLoc1
         put sTouchArray[tPointTwo]["startloc"] into tStartLoc2
         if tStartLoc1 is not empty and tStartLoc2 is not empty then
            put true into pinchflag -- to avoid a jump in location when 1 finger is removed
            
            -- calculate the focus point of the zoom, it is located between the two starting touchpoints
            put item 1 of tStartLoc1 into focusx1
            put item 2 of tStartLoc1 into focusy1
            
            put item 1 of tStartLoc2 into focusx2
            put item 2 of tStartLoc2 into focusy2
            
            put focusx1 + round ((focusx2-focusx1)/2) into focusx
            put focusy1 + round ((focusy2-focusy1)/2) into focusy
            
            put resizeDistance(tStartLoc1, tStartLoc2) into tStartDistance
            put resizeDistance(sTouchArray[tPointOne]["currentloc"], sTouchArray[tPointTwo]["currentloc"]) into tCurrentDistance
            lock screen
            resizeGraphic tStartDistance, tCurrentDistance
            repeat with l = 1 to tMax
               put l into tNo
               if tData[l]["name"] is "signature" then
                  resizeImages tNo, tStartDistance, tCurrentDistance
               else
                  resizeFields tNo, tStartDistance, tCurrentDistance
               end if
            end repeat
            unlock screen
         end if
      end if
   end if
end touchMove

function resizeDistance pLoc1, pLoc2
   local dy, dx, tDistance
   
   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*dy) + (dx*dx)) into tDistance
   
   return tDistance
end resizeDistance 

on resizeGraphic pStartDistance, pNewDistance
   # Work out the percentage change between the old and new image
   put round((pNewDistance / pStartDistance) * 100) into tPercentage
   
   # Calculate the new width and height
   set the width of img "document"  to round(sFRAMEWIDTH * (tPercentage / 100))
   set the height of img "document" to round(sFRAMEHEIGHT * (tPercentage / 100))
   
   -- first scale the coordinates of the focus point
   put tempimagex + round((focusx-tempimagex) * (tPercentage / 100)) into focusxnew
   put tempimagey + round((focusy-tempimagey) * (tPercentage / 100)) into focusynew
   
   -- getting the difference between original and scaled focuspoint
   put focusx - focusxnew into focusxdiff
   put focusy - focusynew into focusydiff
   
   -- calculate the new location of the graphic
   put tempimagex + focusxdiff into locxnew
   put tempimagey + focusydiff into locynew
   set the loc of img "document"  to  locxnew,locynew
end resizeGraphic

on resizeFields pNo, pStartDistance, pNewDistance
   # Work out the percentage change between the old and new image
   put round((pNewDistance / pStartDistance) * 100) into tPercentage
   
   # Calculate the new width and height
   set the width of fld tData[pNo]["name"] to round(tData[pNo]["sFIELDWIDTH"] * (tPercentage / 100))
   set the height of fld tData[pNo]["name"] to round(tData[pNo]["sFIELDHEIGHT"] * (tPercentage / 100))
   set the textSize of fld tData[pNo]["name"] to round((tData[pNo]["sFIELDHEIGHT"] * (tPercentage / 100))/2)
   
   
   -- first scale the coordinates of the focus point
   put tData[pNo]["tempfieldx"] + round((focusx - tData[pNo]["tempfieldx"]) * (tPercentage / 100)) into focusxnew
   put tData[pNo]["tempfieldy"] + round((focusy- tData[pNo]["tempfieldy"]) * (tPercentage / 100)) into focusynew
   
   -- getting the difference between original and scaled focuspoint
   put focusx - focusxnew into focusxdiff
   put focusy - focusynew into focusydiff
   
   -- calculate the new location of the graphic
   put tData[pNo]["tempfieldx"] + focusxdiff into locxnew
   put tData[pNo]["tempfieldy"] + focusydiff into locynew
   set the loc of fld tData[pNo]["name"] to locxnew,locynew
end resizeFields

on resizeImages pNo, pStartDistance, pNewDistance
   # Work out the percentage change between the old and new image
   put round((pNewDistance / pStartDistance) * 100) into tPercentage
   
   # Calculate the new width and height
   set the width of img tData[pNo]["name"] to round(tData[pNo]["sFIELDWIDTH"] * (tPercentage / 100))
   set the height of img tData[pNo]["name"] to round(tData[pNo]["sFIELDHEIGHT"] * (tPercentage / 100))
   set the textSize of img tData[pNo]["name"] to round((tData[pNo]["sFIELDHEIGHT"] * (tPercentage / 100))/2)
   
   
   -- first scale the coordinates of the focus point
   put tData[pNo]["tempfieldx"] + round((focusx - tData[pNo]["tempfieldx"]) * (tPercentage / 100)) into focusxnew
   put tData[pNo]["tempfieldy"] + round((focusy- tData[pNo]["tempfieldy"]) * (tPercentage / 100)) into focusynew
   
   -- getting the difference between original and scaled focuspoint
   put focusx - focusxnew into focusxdiff
   put focusy - focusynew into focusydiff
   
   -- calculate the new location of the graphic
   put tData[pNo]["tempfieldx"] + focusxdiff into locxnew
   put tData[pNo]["tempfieldy"] + focusydiff into locynew
   set the loc of img tData[pNo]["name"] to locxnew,locynew
end resizeImages





williamdesmet
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 66
Joined: Tue Jun 26, 2012 7:07 pm

Re: Pinch and Zoom - Livecode lesson modification

Post by williamdesmet » Thu Nov 10, 2022 9:58 am

@okk/Oliver: This is great and works much better than the code in the Livecode lesson!
I am still wishing someone would suggest or implement 'rotate' into this code.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9801
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Pinch and Zoom - Livecode lesson modification

Post by FourthWorld » Thu Nov 10, 2022 6:24 pm

williamdesmet wrote:
Thu Nov 10, 2022 9:58 am
@okk/Oliver: This is great and works much better than the code in the Livecode lesson!
No one else took action, so I wrote to Support back when this was mentioned here and recently got word that the Lesson code has been updated.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

williamdesmet
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 66
Joined: Tue Jun 26, 2012 7:07 pm

Re: Pinch and Zoom - Livecode lesson modification

Post by williamdesmet » Thu Nov 10, 2022 7:40 pm

Oops, I did not check the lesson before posting.
Good to see the lesson is updated now.

---

Adding rotation would make it a perfect.
I am still struggling with this.
Anyone?

williamdesmet
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 66
Joined: Tue Jun 26, 2012 7:07 pm

Re: Pinch and Zoom - Livecode lesson modification

Post by williamdesmet » Fri Nov 11, 2022 9:54 am

And the same code works in a text field!
I added textsize and margins to it and pinch zoom works fine.

Code: Select all

set the textSize of fld "tekst" to  round(sFRAMEHEIGHT * (tPercentage / 100)) 
set the margins of fld "tekst" to textSize / 3

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”