# Swipe Handling

For a project of mine I needed some simple code to detect swipes. I’ve seen people ask how to do it before, so I figured I’d go ahead and share it here (along with a simple code in main showing how it’s used)

Basically it works as so: A swipe must be of a certain length and time and not distance too far vertically or horizontally depending on the direction of the swipe. You can call `Swipes:getSwipe()` and it will return a vector based on how much you swiped (Ex a long swipe right would return vec2(3.2, 0) whereas a short swipe down would return vec2(0, -1.3)

Enough talking, here’s the code:

``````
--# Main
-- Swiper

-- Use this function to perform your initial setup
function setup()
swiper = Swipes()

x = WIDTH / 2
y = HEIGHT / 2
end

-- This function gets called once every frame
function draw()
background(255, 255, 255, 255)

stroke(0, 155, 255, 255) strokeWidth(2) noFill()

local drawX, drawY = x % WIDTH, y % HEIGHT
ellipse(drawX, drawY, 100)
end

function touched(t)
-- Pass touch along to swipe handler
swiper:touched(t)

if t.state == ENDED then
-- Get the swipe and use it to move the ball
local s = swiper:getSwipe()
tween(math.abs(0.2 * s.x), _G, { x = x + s.x * 100 }, tween.easing.linear)
tween(math.abs(0.2 * s.y), _G, { y = y + s.y * 100 }, tween.easing.linear)
end
end

--# Swipes
Swipes = class()

function Swipes:init()
self.allowedMargin = WIDTH / 10
self.swipeLen = WIDTH / 21
self.allowedTime = 2

self.firstTouch = nil
self.lastTouch = nil
self.startTime = nil
self.endTime = nil

self.swipe = vec2(0, 0)
end

function Swipes:getSwipe()
local ret = self.swipe or vec2(0,0)
self.swipe = vec2(0,0)

return ret
end

function Swipes:findSwipes()
if self.startTime == nil or self.endTime == nil or self.endTime - self.startTime > self.allowedTime then return end
if self.firstTouch == nil or self.lastTouch == nil then self.firstTouch = nil self.lastTouch = nil return end

if self.lastTouch.x - self.firstTouch.x >= self.swipeLen and math.abs(self.lastTouch.y - self.firstTouch.y) <= self.allowedMargin then
-- Swiped right
local amp = (self.lastTouch.x - self.firstTouch.x) / self.swipeLen
self.swipe = vec2(amp, 0)
elseif self.firstTouch.x - self.lastTouch.x >= self.swipeLen and math.abs(self.lastTouch.y - self.firstTouch.y) <= self.allowedMargin then
-- Swiped left
local amp = (self.lastTouch.x - self.firstTouch.x) / self.swipeLen
self.swipe = vec2(amp, 0)
elseif self.lastTouch.y - self.firstTouch.y >= self.swipeLen and math.abs(self.lastTouch.x - self.firstTouch.x) <= self.allowedMargin then
-- Swiped up
local amp = (self.lastTouch.y - self.firstTouch.y) / self.swipeLen
self.swipe = vec2(0, amp)
elseif self.firstTouch.y - self.lastTouch.y >= self.swipeLen and math.abs(self.lastTouch.x - self.firstTouch.x) <= self.allowedMargin then
-- Swiped down
local amp = (self.lastTouch.y - self.firstTouch.y) / self.swipeLen
self.swipe = vec2(0, amp)
end

self.firstTouch = nil
self.lastTouch = nil
end

function Swipes:touched(t)
if t.state == BEGAN and self.firstTouch == nil then
self.firstTouch = t
self.startTime = ElapsedTime
end

if t.state == ENDED and self.lastTouch == nil then
self.lastTouch = t
self.endTime = ElapsedTime

self:findSwipes()
end
end
``````

@JakAttak I looked thru my collection of code and found this swipe program. Thought I’d share it while we’re on the subject. Swipe in the direction you want the circle to go. Speed is determined by the length of the swipe.

``````
displayMode(FULLSCREEN)

function setup()
speed=30    -- set initial speed value
swipe=vec3(0,0,0)    -- initialize swipe variable
x=WIDTH/2    -- starting x location
y=HEIGHT/2   -- starting y location
end

function draw()
background(40,40,50)    -- set background color
fill(255)    -- white color for circle
text("Swipe for direction, length for speed",WIDTH/2,HEIGHT-100)
ellipse(x,y,40)    -- draw a circle at x,y with size of 40
if swipe.z>0 then    -- check if a swipe occured
x=x+swipe.x*swipe.z    -- add x swipe speed to x value
y=y+swipe.y*swipe.z    -- add y swipe speed to y value
end
end

function touched(t)
if t.state==BEGAN then    -- start of swipe
ts=vec2(t.x,t.y)    -- save touch start values
end
if t.state==ENDED then    -- end of swipe
d=vec2(t.x,t.y):dist(vec2(ts.x,ts.y))    -- calculate swipe distance
td=vec2(t.x-ts.x,t.y-ts.y):normalize()    -- x,y movement
swipe=vec3(td.x,td.y,d/speed)    -- set swipe variable x,y,speed
end
end

``````

Hi ! these codes looks really good ! But I think a swipe should be short in time (1 or 2 seconds max). Is there a way to handle that ?

@RyZum sure! You just save the time of the first and last touches, then compare them to see if the time in between is short enough. I’ve made the changes necessary in the code in the original post.

Simply change the allowedTime variable in the swipe class to however long you choose.

@Ryzum You could start a timer when the touch state equals BEGAN and then when the touch state equals MOVING you could check the timer. When the timer reaches the value you want (1 or 2 sec), stop changing the x and y values and process the swipe. When the touch state equals ENDED, you can either process the swipe if it you didn’t do it when MOVING, or ignore the swipe if you did it in MOVING.

Great ! Thanks.