Recently at Flatiron School, my project partner and I created a single-page application that hosted a variety of games. The site came together nicely. It featured games like Tic-Tac-Toe, Connect-4, and 6144 (our take on 2488). We even deployed it on Heroku, so our friends and family could enjoy and marvel at our work. I sent frantic texts and discord messages to all my friends urging them to check out the fruit of our labor. The first message I received broke my heart.
“Hey the site looks great, but I can’t play 6144, or their clones on my phone :(“
That makes sense, all the other games work by clicking your mouse on the board, and what are your fingers if not ten apposable mice. But, we programmed 6144 to listen for arrow-key presses to manipulate the game board. No arrow-keys, no gameplay. I figured this should be easy to fix, just add an event listener to the game that will listen for swipes, except that doesn’t exist. How is that possible? You can swipe on Tinder! The technology should exist! The easy route would be to swallow my frustration and tell my friend to try the app on a desktop or laptop, but the easy route is boring. Instead, I embarked on a journey to make our site mobile-friendly (also objectively better than Tinder since we will two extra swipe directions) and I will bring you, my dear reader, along for the ride!
Our swipe feature is three different event listeners wrapped in one function:
- Touch start will handle the logic for the beginning of our swipe
- Touch move will handle the logic for the duration of the swipe
- Touch end (the meat and potatoes of the function) will handle the logic for determining which direction we swiped
Our encompassing function will take two arguments:
- “el”: The HTML element we want on swipes to effect
- “callback”: The callback function that we will use to handle functionality
Before we start making events willy-nilly, we need to define some variables that those events can use. Most of these will be defined in other places in our function, but it’s nice to get have them ready for when we need them.
While start by defining our element to a variable called “touchsurface”. Next, we need to define our threshold and restraint. The threshold will define our minimum travel distance that will register a swipe. Let’s set that to 150 to root out any unintended touches from triggering out events. Restraint will determine how far you can move on a perpendicular axis, in layman’s terms we do not want our swipes to be angled, just up horizontal and vertical. The last term we want to define is “allowedTime” which (as the name suggests) defines how long the user has to move their finger. Now that we have our groundwork laid out, let’s start eventing!
Our first event listener will be the start of the swipe. We’ll define ‘touchobj’ as the first item in the TouchList, which we can grab from the changeTouches array. “startX” and “startY” indicate the location of the touch on an X and Y-axis. Next, we’ll set a start time using the date object, and prevent default will stop any touches from counting as clicks. And just like that, we finished a third of the swipe event.
The second event listener is a simple one. We just need to prevent the default action during a touch move; scrolling.
Now, this is where the fun begins, and by fun I mean math. Our last event listener will handle all the logic required to calculate a swipe. Just like before we start by defining where our touch ends from the TouchList. Next, we subtract our start touch from our end touch for each axis (X and Y). This will give us the distance our finger traveled. Then, we calculate how long the duration of the swipe was by setting a new time and subtracting our initial time. If our elapsed time was less than or equal to the time that we allow (300), the function will move on to calculating the direction of our swipe. To do that, we will need to take the absolute value of our X and Y distance (luckily JS has a built-in function for that Math.abs()) and compare it to our threshold and restraint. We use the absolute value because about 25% of the time our distance will be a negative number (more on that later). If our X or Y is greater than the threshold and we don't drift too far in a perpendicular axis we have a swipe!
To determine our direction we need to use my favorite operator: a ternary operator. If the condition we set is true the left side of the colon is used, if not we’ll use the right side. If our distance along an axis is a negative number we know that we moved either left or up, depending on which axis. Using this helpful graph as an example, if we start at 8 and move to 4 along the X-axis, our distance (4–8) will be -4 resulting in a leftward swipe.
We finally have our swipe direction! Now we just need to make our swipes do something by making a function to handle our swipes. In our app, our player movement was already split up by direction, so I plugged those functions under if statements that scan for directions. I also added a conditional to check if the user is on a mobile device.
The beauty of software development is if something doesn't exist we can make it ourselves and learn new concepts along the way. Now that our site is 100% mobile-friendly we can move on to whatever our next project is.