SlideShare a Scribd company logo
1 of 10
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().
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)
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();

}
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() {
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
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
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)))
{
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;
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.
Replicate iPhone Gallery Swipe for Mobile Web

More Related Content

Similar to Replicate iPhone Gallery Swipe for Mobile Web

YUI for Mobile - HTML5DevConf 11
YUI for Mobile - HTML5DevConf 11YUI for Mobile - HTML5DevConf 11
YUI for Mobile - HTML5DevConf 11Gonzalo Cordero
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsNaman Dwivedi
 
Sharepoint 2013 - un slider JSSOR sur bib Images
Sharepoint 2013 - un slider JSSOR sur bib ImagesSharepoint 2013 - un slider JSSOR sur bib Images
Sharepoint 2013 - un slider JSSOR sur bib ImagesEmmanuel Sotter
 
Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Massimo Bonanni
 
Oculus Rift DK2 + Leap Motion Tutorial
Oculus Rift DK2 + Leap Motion TutorialOculus Rift DK2 + Leap Motion Tutorial
Oculus Rift DK2 + Leap Motion TutorialChris Zaharia
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in AndroidRobert Cooper
 
Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!Massimo Bonanni
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simplerAlexander Mostovenko
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...GeeksLab Odessa
 
How to implement react native animations using animated api
How to implement react native animations using animated apiHow to implement react native animations using animated api
How to implement react native animations using animated apiKaty Slemon
 
An Event Apart Boston: Principles of Unobtrusive JavaScript
An Event Apart Boston: Principles of Unobtrusive JavaScriptAn Event Apart Boston: Principles of Unobtrusive JavaScript
An Event Apart Boston: Principles of Unobtrusive JavaScriptPeter-Paul Koch
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013Mathias Seguy
 
04 activities - Android
04   activities - Android04   activities - Android
04 activities - AndroidWingston
 
Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Massimo Bonanni
 
Jquery tutorial-beginners
Jquery tutorial-beginnersJquery tutorial-beginners
Jquery tutorial-beginnersIsfand yar Khan
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Gabor Varadi
 

Similar to Replicate iPhone Gallery Swipe for Mobile Web (20)

Advanced Silverlight
Advanced SilverlightAdvanced Silverlight
Advanced Silverlight
 
YUI for Mobile - HTML5DevConf 11
YUI for Mobile - HTML5DevConf 11YUI for Mobile - HTML5DevConf 11
YUI for Mobile - HTML5DevConf 11
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animations
 
Yui mobile
Yui mobileYui mobile
Yui mobile
 
Sharepoint 2013 - un slider JSSOR sur bib Images
Sharepoint 2013 - un slider JSSOR sur bib ImagesSharepoint 2013 - un slider JSSOR sur bib Images
Sharepoint 2013 - un slider JSSOR sur bib Images
 
Android 3
Android 3Android 3
Android 3
 
Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
Oculus Rift DK2 + Leap Motion Tutorial
Oculus Rift DK2 + Leap Motion TutorialOculus Rift DK2 + Leap Motion Tutorial
Oculus Rift DK2 + Leap Motion Tutorial
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!Project Gesture & Real Sense: il potere nelle mani!!
Project Gesture & Real Sense: il potere nelle mani!!
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
How to implement react native animations using animated api
How to implement react native animations using animated apiHow to implement react native animations using animated api
How to implement react native animations using animated api
 
An Event Apart Boston: Principles of Unobtrusive JavaScript
An Event Apart Boston: Principles of Unobtrusive JavaScriptAn Event Apart Boston: Principles of Unobtrusive JavaScript
An Event Apart Boston: Principles of Unobtrusive JavaScript
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013
 
04 activities - Android
04   activities - Android04   activities - Android
04 activities - Android
 
Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!
 
Jquery tutorial-beginners
Jquery tutorial-beginnersJquery tutorial-beginners
Jquery tutorial-beginners
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 

Recently uploaded

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 

Recently uploaded (20)

Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 

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.