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

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
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
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 

Recently uploaded (20)

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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 ...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
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.