Pinch zoom + pan
Monkey Forums/Monkey Programming/Pinch zoom + pan
| ||
Has anyone successfully implemented something like this? Pinch to zoom + drag to pan. I've been pulling my hair out for 3 days (for a few hours each day, but still...) and I can't get it right. I've got this far (pseudocode): offset -= O offset *= newZoom offset += beginO + pan O = origin newZoom = distance between points over distance between the original points (eg.: 2 if your fingers are twice as far apart as they were when starting the zoom) beginO = origin when zoom/pan was started pan = difference between the current points and the original points I've been circling around the idea that I have to invert the current transformation (object.x = O.x + position.x * zoom) and then apply the new one, but I just can't get it right and my head hurts :( |
| ||
There are gesture events that do a lot of this for you - they are just not implemented into Monkey yet. In javascript you are looking at something like: As you can clearly see, scale and rotation are calculated for you - same for native iOS, not sure about andriod but I suspect it's native. |
| ||
my 'transform' example in the bananas directory show how to do the transformations. You just need to pick your pan, zoom and rotate values. |
| ||
Something like this code should let you do pan with finger:If drag = False If TouchHit(0) drag = True dragStartX = TouchX(0) dragStartY = TouchY(0) dragScrollX = scrollX dragScrollY = scrollY EndIf Else If TouchDown(0) = False drag = False Else dragCurrentX = TouchX(0) dragCurrentY = TouchY(0) EndIf dragAmountX = dragCurrentX - dragStartX dragAmountY = dragCurrentY - dragStartY scrollX = dragScrollX + dragAmountX scrollY = dragScrollY + dragAmountY EndIf You just need to offset/transform your drawing with scrollX/scrollY |
| ||
Thanks for the help guys. My original problem wasn't that I can't zoom or pan. I nailed those really quick. The problem was that if I zoomed while panning, my objects would move all over the place. Also, I couldn't get the zooming to be properly centered between my fingers. I got to a point that's satisfying for now, but it's still not perfect. (might be precision problems, but I doubt it) Global ZoomPan1Begin:Float[2] Global ZoomPan2Begin:Float[2] Global ZoomPanDO:Float[2] Global ZoomPanZoom:Float if (Not TouchDown(1)) ZoomPanning = false End If (TouchDown(0) and TouchHit(1)) ZoomPan1Begin[0] = TouchX(0) ZoomPan1Begin[1] = TouchY(0) ZoomPan2Begin[0] = TouchX(1) ZoomPan2Begin[1] = TouchY(1) ZoomPanDO[0] = DOX ZoomPanDO[1] = DOY ZoomPanZoom = GetZoom() ZoomPanning = True End If (ZoomPanning) Local oldDist# = Dist2DSq(ZoomPan1Begin[0], ZoomPan1Begin[1], ZoomPan2Begin[0], ZoomPan2Begin[1]) Local crtDist# = Dist2DSq(TouchX(0), TouchY(0), TouchX(1), TouchY(1)) Local newZoom# = crtDist / oldDist SetZoom(ZoomPanZoom * newZoom) Local newP:Float[2] newP[0] = (TouchX(0) + TouchX(1)) / 2.0 newP[1] = (TouchY(0) + TouchY(1)) / 2.0 Local oldP:Float[2] oldP[0] = (ZoomPan1Begin[0] + ZoomPan2Begin[0]) / 2.0 oldP[1] = (ZoomPan1Begin[1] + ZoomPan2Begin[1]) / 2.0 Local newOff:Float[2] newOff[0] = -newP[0] * (newZoom - 1.0) + newP[0] - oldP[0] newOff[1] = -newP[1] * (newZoom - 1.0) + newP[1] - oldP[1] DOX = ZoomPanDO[0] + newOff[0] DOY = ZoomPanDO[1] + newOff[1] End @Indiepath Until monkey has native support for gestures, I'd like to code them myself (besides learning stuff, I avoid hacking stuff for each target) :) @Warpy I saw the example and I know how to play with those. I guess I'm trying to solve it without matrices because I started this way. I'll probably end up with matrices in the end though. @Skn3 Thanks for the code, but I already had that :) |
| ||
Thanks for the help guys. My original problem wasn't that I can't zoom or pan. I nailed those really quick. The problem was that if I zoomed while panning, my objects would move all over the place. Also, I couldn't get the zooming to be properly centered between my fingers. I got to a point that's satisfying for now, but it's still not perfect. (might be precision problems, but I doubt it) Global ZoomPan1Begin:Float[2] Global ZoomPan2Begin:Float[2] Global ZoomPanDO:Float[2] Global ZoomPanZoom:Float if (Not TouchDown(1)) ZoomPanning = false End If (TouchDown(0) and TouchHit(1)) ZoomPan1Begin[0] = TouchX(0) ZoomPan1Begin[1] = TouchY(0) ZoomPan2Begin[0] = TouchX(1) ZoomPan2Begin[1] = TouchY(1) ZoomPanDO[0] = DOX ZoomPanDO[1] = DOY ZoomPanZoom = GetZoom() ZoomPanning = True End If (ZoomPanning) Local oldDist# = Dist2DSq(ZoomPan1Begin[0], ZoomPan1Begin[1], ZoomPan2Begin[0], ZoomPan2Begin[1]) Local crtDist# = Dist2DSq(TouchX(0), TouchY(0), TouchX(1), TouchY(1)) Local newZoom# = crtDist / oldDist SetZoom(ZoomPanZoom * newZoom) Local newP:Float[2] newP[0] = (TouchX(0) + TouchX(1)) / 2.0 newP[1] = (TouchY(0) + TouchY(1)) / 2.0 Local oldP:Float[2] oldP[0] = (ZoomPan1Begin[0] + ZoomPan2Begin[0]) / 2.0 oldP[1] = (ZoomPan1Begin[1] + ZoomPan2Begin[1]) / 2.0 Local newOff:Float[2] newOff[0] = -newP[0] * (newZoom - 1.0) + newP[0] - oldP[0] newOff[1] = -newP[1] * (newZoom - 1.0) + newP[1] - oldP[1] DOX = ZoomPanDO[0] + newOff[0] DOY = ZoomPanDO[1] + newOff[1] End @Indiepath Until monkey has native support for gestures, I'd like to code them myself (besides learning stuff, I avoid hacking stuff for each target) :) @Warpy I saw the example and I know how to play with those. I guess I'm trying to solve it without matrices because I started this way. I'll probably end up with matrices in the end though. @Skn3 Thanks for the code, but I already had that :) |