I have a code where I have a control panel (simplified to a white rectangle in the code below) that I want the user to be able to drag / flick.
I got the drag functionality to work pretty well, but I can't get the flick working (acceleration caused by the drag) properly.
I think it tracked the problem to the way I calculate the acceleration in the lines:
1 2 | local flickSpeed = ((localEventY-t.y0) / dT )*.001 local newYAfterAcelleration = setToWithinLimits((t.y+flickSpeed),lowestDragPos,highestDragPos |
Nokia did a great writeup on kinetic scrolling: http://www.developer.nokia.com/Community/Wiki/Qt_Kinetic_scrolling_-_from_idea_to_implementation
Calculating velocity is important: v = d / t
http://ceres.hsc.edu/homepages/classes/astronomy/fall97/Mathematics/sec5.html
Thanks. The Nokia article was an interesting reading.
I was able to solve the problem by recording the initial event.y position and using it to calculate the finger distance movement. I also used a new t.direction valuable to store the direction of the last finger movement.
here is the new code if it helps anyone in the future:
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 | ------------------- --helper function ------------------- local function setToWithinLimits(setTo,lowerLimit,upperLimit) local result if (setTo > upperLimit ) then result = upperLimit elseif (setTo < lowerLimit) then result = lowerLimit else result = setTo end return result end ------------------- --objects ------------------- local localGroup=display.newGroup() local panelGroup = display.newGroup() localGroup:insert(panelGroup) local panelBG = display.newRect(0,0,200,display.contentHeight*2) panelBG:setFillColor(255,255,255) local referenceObject=display.newCircle(20,100,5) referenceObject:setFillColor(0,255,0) panelGroup:insert(panelBG) panelGroup:insert(referenceObject) ------------------- --drag function ------------------- local function dragPanel( event ) local t = event.target local phase = event.phase local highestDragPos = panelBG.contentHeight + display.contentHeight local lowestDragPos = 0 local initialTimeMsec = system.getTimer() local localEventX , localEventY = t.parent:contentToLocal(event.x,event.y) if "began" == phase then display.getCurrentStage():setFocus( t, event.id ) t.isFocus = true -- Store initial position t.y0 = localEventY - t.y t.lastY = localEventY initialTimeMsec = system.getTimer() elseif t.isFocus then if "moved" == phase then local newY = localEventY - t.y0 if t.y>newY then t.direction=-1 else t.direction=1 end print(t.direction) t.y = setToWithinLimits(newY,lowestDragPos,highestDragPos) elseif "ended" == phase or "cancelled" == phase then -- calc speed local dT = system.getTimer() - initialTimeMsec local flickSpeed = t.direction*math.abs(((localEventY-t.lastY) / dT ))*.01 local newYAfterAcelleration = setToWithinLimits((t.y+flickSpeed),lowestDragPos,highestDragPos) transition.to(t,{y=newYAfterAcelleration,transition=easing.outExpo}) display.getCurrentStage():setFocus( t, nil ) t.isFocus = false end end return true end panelGroup:addEventListener("touch",dragPanel) |