The document discusses the JavaScript code for replicating the swipe gesture gallery on the iPhone for mobile web applications using HTML5. It describes creating a self-calling function that defines a swipey object containing properties and methods. Key aspects covered include initializing events, handling touch start, move and end events, calculating swipe distance and direction, and translating the slide container for navigation. Methods like moveLeft(), moveRight() and comeBack() translate the container for sliding between images.
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
Replicate iPhone Gallery Swipe for Mobile Web
1. Replicating the Swipe Gesture iPhone Gallery for mobile web– HTML5
– Part 2
http://jbkflex.wordpress.com/2012/01/12/replicating-the-swipe-gesture-iphone-gallery-for-mobile-
web-html5-part-2/
Gesture Interaction – The JavaScript code
By looking at the java script code you might have a question in your mind that this time I have used a different way of
writing my javascript code. What I have done is that I have created a self calling function and I have defined an object
(swipey) inside the function and finally exposed the object to the window object (window.swipeyObj = swipey) so
that I can call the properties and methods of the swipey object anywhere after including the javascript file to our
library. Ofcourse there are several other ways to execute the same, but this way it maintains the scope of the
properties and methods of the object.
Let’s go straight to the swipey object which follows a JSON pattern. Inside the swipey object we have defined a
series of properties and the methods. Think of it as a Class, but there are slight differences between a JSON Object
and a Class. We will not go into that at the moment. The basic structure of swipey object is shown below,
var swipey = {
property1:value1,
property2:value2,
……………
method1:function(){},
method2:function(){},
……………
};
To access a property we write swipey.property1 and to call a method swipey.method1(). Ok, that’s quite a brief
description of a JSON object. Also, at most places I have provided comments for understanding. Now,
theinitSwipey() method defines some basic operations which is simple enough to understand. window.scrollTo(0,
1);is for hiding the address bar of the browser to give the app a native look. I have already talked about it in details in
my earlier post, here. One thing to be noticed is the line below,
swipey.slideContainer.style.width = swipey.slides.length * swipey.preferredWidth +
"px";
If you remember we should have our slides (<li>) horizontally placed and for that we have set float:left in CSS. But
that is not enough for them to be placed horizontally inside the container (<ul>) element. We also need to provide
enough space to the container so that all the slides are arranged horizontally and for that we have to set the width of
the container to
width_of_container = number_of_slides * width_of_one_slide;
We could have hardcoded the value of width in CSS, but to keep things dynamic I have done it in script block. Now,
it doesnot matter how many slides you add, you do not have to calculate the width value manually and change it in
CSS. The script will do it for you. Finally, the last line of initSwipey() makes a call to initEvents().
2. Inside initEvents() function all the event listeners are registered. This is a touch based app so we have touch
events. Note that I have added the event listeners to the wrapper. You can add it to the container <ul> element also. I
felt it better to add to the wrapper.
Next up, for each touch based event I have defined listener functions which will handle the actions when the
corresponding event is fired.
startHandler function()
This function is called when touch start event is fired. Inside it we mainly store the starting X co-ordinate of the touch
point and save it in swipey.startX. Also we set our timer on.
moveHandler function()
This function is called when the figer moves over the device screen. It is called repeatedly each time the finger is
moved. Here we calculate the net distance that the container should move relative to the start point
swipey.distanceX = event.touches[0].pageX - swipey.startX;
and then we translate the container <ul> element by that much distance. Now which direction – left or right depends
on the value of distanceX, if it is negative it moves to the left and if positive moves to the right.
swipey.slideContainer.style.webkitTransform = "translate3d(" + (swipey.distanceX +
swipey.currentDistance) + "px, 0,0)";
Also we have a value of currentDistance added to the distanceX. This is because when we translate the <ul> element
the co-ordinate system moves by that distance. So next time whenever it is moved again the earlier position should
be taken into consideration.
endHandler function()
And then we have our endHandler() function which is called when the finger leaves the screen. Here the final
movement is made based on the direction. We check the following conditions here,
1) The direction of movement – left or right
if (swipey.distanceX > 0) {
swipey.direction = "right";
}
if (swipey.distanceX < 0) {
swipey.direction = "left";
}
2) If it is the beginning of the gallery and you are swiping to the right then the images will come back / If it
is the end of the gallery and you are swiping to the left then the images will come back. (Feature no. 4 from
the list that I discussed in Part1)
3. if ((swipey.direction == "right" && swipey.currentDistance == 0) || (swipey.direction
== "left" && swipey.currentDistance == -(swipey.maxDistance - swipey.preferredWidth)))
{
swipey.comeBack();
}
3) If the swiping is very fast and instantly you flicker the images with minimum distance swiped is 10 for
right direction and -10 for left, then the previous slide or the next slide is displayed respectively. (Feature no.
2 from the list that I discussed in Part1)
else if (swipey.timerCounter < 30 && swipey.distanceX > 10) {
swipey.moveRight();
}
else if (swipey.timerCounter < 30 && swipey.distanceX < -10) {
swipey.moveLeft();
}
4) If you swipe the current image a minimum distance of half the screen width then the next or previous
image is displayed based on the direction of swipe. (Feature no. 1 from the list that I discussed in Part1)
else if (swipey.distanceX <= -(swipey.preferredWidth / 2)) //-320/2
swipey.moveLeft();
}
else if (swipey.distanceX >= (swipey.preferredWidth / 2)) //320/2
swipey.moveRight();
}
5) If any of the conditions are not met then the image will come back to its original position. (Feature no. 3
from the list that I discussed in Part1)
else {
swipey.comeBack();
}
4. Next, there are specific methods for translating/moving the slide container to left or right and also come back to
current position.
moveLeft: function() {
swipey.currentDistance += -swipey.preferredWidth;
swipey.slideContainer.style.webkitTransitionDuration = 300 + "ms";
//using CSS3 transformations - translate3d function for movement
swipey.slideContainer.style.webkitTransform = "translate3d(" +
swipey.currentDistance + "px, 0,0)";
},
moveRight: function() {
swipey.currentDistance += swipey.preferredWidth;
swipey.slideContainer.style.webkitTransitionDuration = 300 + "ms";
swipey.slideContainer.style.webkitTransform = "translate3d(" +
swipey.currentDistance + "px, 0,0)";
},
comeBack: function() {
swipey.slideContainer.style.webkitTransitionDuration = 250 + "ms";
swipey.slideContainer.style.webkitTransitionTimingFunction = "ease-out";
swipey.slideContainer.style.webkitTransform = "translate3d(" +
swipey.currentDistance + "px, 0,0)";
}
moveLeft() and moveRight() are very similar, only the calculation of swipey.currentDistance variable is
different.Note that we have to translate the <ul> slide container by 320px(preferredWidth) left or right everytime for
the neighboring slides to be visible. And finally we expose the swipey object to the global window object.
window.swipeyObj = swipey;
Finally we have the full java script code below with inline comments,
(function() {
5. var swipey = {
slideContainer: null, //<ul> element object that holds the image slides
wrapper: null, //meant for masking/clipping
slides: null, //array of all slides i.e <li> elements
distanceX: 0, //distance moved in X direction i.e left or right
startX: 0, //registers the initial touch co-ordinate
preferredWidth: 0, //dynamic variable to set width
preferredHeight: 0, //dynamic variable to set height
direction: "", //direction of movement
timer: null, //timer that set starts when touch starts
timerCounter: 0, //counter variable for timer
isTouchStart: false, //boolen to chk whether touch has started
maxDistance: 0, //maximum distance in X direction that slide container can move
currentDistance: 0, //current distance moved by slide container through translate
initSwipey: function() {
//scroll the window up to hide the address bar of the browser.
window.setTimeout(function() { window.scrollTo(0, 1); }, 100);
//get all the instances of the HTML elements
swipey.wrapper = document.getElementById("wrapper");
swipey.slideContainer = document.getElementById("slideContainer");
swipey.slides = slideContainer.getElementsByTagName("li");
//for iPhone, the width and height
6. swipey.preferredWidth = 320;
swipey.preferredHeight = 416; //510 for android
//setting the width and height to our wrapper with overflow = hidden
swipey.wrapper.style.width = swipey.preferredWidth + "px";
swipey.wrapper.style.height = swipey.preferredHeight + "px";
//setting the width to our <ul> element which holds all the <li> elements
swipey.slideContainer.style.width = swipey.slides.length * swipey.preferredWidth +
"px";
swipey.slideContainer.style.height = swipey.preferredHeight + "px";
//calculating the max distance of travel for Slide Container i.e <ul> element
swipey.maxDistance = swipey.slides.length * swipey.preferredWidth;
//initialize and assign the touch events
swipey.initEvents();
},
initEvents: function() {
//registering touch events to the wrapper
swipey.wrapper.addEventListener("touchstart", swipey.startHandler, false);
swipey.wrapper.addEventListener("touchmove", swipey.moveHandler, false);
swipey.wrapper.addEventListener("touchend", swipey.endHandler, false);
},
//funciton called when touch start event is fired i.e finger is pressed on the screen
startHandler: function(event) {
//stores the starting X co-ordinate when finger touches the device screen
swipey.startX = event.touches[0].pageX; //.changedTouches[0]
//timer is set on
7. swipey.timer = setInterval(function() { swipey.timerCounter++; }, 10);
swipey.isTouchStart = true;
event.preventDefault(); //prevents the window from scrolling.
},
//funciton called when touch move event is fired i.e finger is dragged over the screen
moveHandler: function(event) {
if (swipey.isTouchStart) {
swipey.distanceX = event.touches[0].pageX - swipey.startX;
//move the slide container along with the movement of the finger
swipey.slideContainer.style.webkitTransform = "translate3d(" + (swipey.distanceX +
swipey.currentDistance) + "px, 0,0)";
}
},
//funciton called when touch end event is fired i.e finger is released from screen
endHandler: function(event) {
clearInterval(swipey.timer); //timer is stopped
if (swipey.distanceX > 0) {
swipey.direction = "right";
}
if (swipey.distanceX < 0) {
swipey.direction = "left";
}
//the following conditions have been discussed in details
if ((swipey.direction == "right" && swipey.currentDistance == 0) || (swipey.direction
== "left" && swipey.currentDistance == -(swipey.maxDistance - swipey.preferredWidth)))
{
8. swipey.comeBack();
}
else if (swipey.timerCounter < 30 && swipey.distanceX > 10) {
swipey.moveRight();
}
else if (swipey.timerCounter < 30 && swipey.distanceX < -10) {
swipey.moveLeft();
}
else if (swipey.distanceX <= -(swipey.preferredWidth / 2)) { //-160
swipey.moveLeft();
}
else if (swipey.distanceX >= (swipey.preferredWidth / 2)) { //160
swipey.moveRight();
}
else {
swipey.comeBack();
}
swipey.timerCounter = 0; //reset timerCounter
swipey.isTouchStart = false; //reset the boolean var
swipey.distanceX = 0; //reset the distance moved for next iteration
},
moveLeft: function() {
swipey.currentDistance += -swipey.preferredWidth;
9. swipey.slideContainer.style.webkitTransitionDuration = 300 + "ms";
//using CSS3 transformations - translate3d function for movement
swipey.slideContainer.style.webkitTransform = "translate3d(" + swipey.currentDistance
+ "px, 0,0)";
},
moveRight: function() {
swipey.currentDistance += swipey.preferredWidth;
swipey.slideContainer.style.webkitTransitionDuration = 300 + "ms";
swipey.slideContainer.style.webkitTransform = "translate3d(" + swipey.currentDistance
+ "px, 0,0)";
},
comeBack: function() {
swipey.slideContainer.style.webkitTransitionDuration = 250 + "ms";
swipey.slideContainer.style.webkitTransitionTimingFunction = "ease-out";
swipey.slideContainer.style.webkitTransform = "translate3d(" + swipey.currentDistance
+ "px, 0,0)";
}
}; //end of swipey object
window.swipeyObj = swipey; //expose to global window object
})();
swipeyObj.initSwipey(); //invoke the init method to get started
The code can be modified and manipulated as per your need. The same logic however, can be used to build the
iPhone/Android carousel menu as well. And here it is, the link for the demo app for mobile
device:http://jbk404.site50.net/html5/mobile/swipey/mobile_version/
Open it in your iPhone or Android smartphone browser and swipe across the screen. For a desktop browser version
(Chrome and Safari – webkit browsers only) here is the link: http://jbk404.site50.net/html5/mobile/swipey/
This completes our two part series of Swipe Gesture gallery. Hope you find it useful.