Websites are used more and more on mobile devices like phones and tablets. These are touch based devices and people are starting to expect they can navigate through a slideshow simply by swiping it left or right.

See for inspiration http://us.blackberry.com which apparantly uses the overscroll plugin (http://azoffdesign.com/overscroll) to create such an effect.

As far as I'm aware this is currently not available functionality in views_slideshow (or any other jquery based slideshow module in Drupal). It would be awesome to see this happen!

CommentFileSizeAuthor
#24 views_slideshow-974482-23.patch2.91 KBstefan.r
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

aaron’s picture

actually, Views Slideshow: ImageFlow does support iPhone touch swipes.

askibinski’s picture

Actually, I used Imageflow and it does not offer this functionality. Basically it's just 'point + click' while I'm talking about 'click(hold) + sweep'.

tchilly’s picture

I would probably use a jQuery plugin like http://plugins.jquery.com/plugin-tags/touch, and apply it to my slideshow. Could be used with jQuery cycle plugin quite easily for creating slideshows.

aaron’s picture

i don't have an iphone to test, @askibinski. could you confirm that on the demo at http://finnrudolph.de/ImageFlow/Introduction as well?

thanks!

askibinski’s picture

@aaron I can confirm the demo does not work as expected on android mobile. I'm pretty sure it's the same on iphone.
The only way to scroll by holding is to use the slider beneath the images, but that's just wrong ;)

By the way, scratch overscroll, that doesn't work on mobile browsers either, but @tchilly's solution seems to be in the right direction.

jon_stewart’s picture

+1 subscribing. The demo doesn't swipe on HTC desire.

redndahead’s picture

Version: 6.x-3.x-dev » 7.x-3.x-dev

Moving to 7 since it's not 6 specific

askibinski’s picture

See also this related issue about flexslider, which support touch gestures.
#1251388: Support FlexSlider

stovak’s picture

Here's an implementation you can put in a global.js in your theme:

https://gist.github.com/1343996

miaoulafrite’s picture

+1 sounds promising

eigentor’s picture

Here are some sliders that work, have not checked how hard they would be to implement
http://unoslider.heroku.com/
http://dimsemenov.com/plugins/royal-slider/
(Royal slider site is no mobile site, swiping the image still works)
Both build as Jquery Plugins.

tchilly’s picture

@9 - Works like a charm!
+1 add into module

jdanthinne’s picture

Status: Active » Needs review

#9 Working fine with Cycle slideshows!

jdanthinne’s picture

And with #9 working, it would be nice to have an option to decide to respond only to swiping left and right OR up and down (OR both like it does now), because when trying to scroll the page up when swiping up over the slideshow, now it moves to the next slide instead of scrolling the page…

kinsker-studio’s picture

@eigentor Thank you so much for tip about RoyalSlider (http://dimsemenov.com/plugins/royal-slider/), saved me so much time

renenee’s picture

I'm pretty sure #9 saved me a ton of time. Thank you so much!

design.er’s picture

@stovak, you are incredible! :)
Thank you soo much for this implementation. It works perfectly on my phone, even with Views Slideshow JCarousel.
It would be really great to see this feature implemented - maybe as an option (checkbox on the settings page).

ChristianP’s picture

#9 Doesn't work for me. I use Drupal 6 and Views Slideshow 6.x 3.0.

Is there something different I need to change in the javascript file?

It's weird because I thought it worked for a second, but then it stopped working. Also is there any specific setting/effect I need to use, or can I use fade as well as slideHorz?

argiope’s picture

I ended up including this as a custom module on my site. It only looks for left and right actions be it could be easily modified to detect up and down and the type easing.

(function( $ ) {
  $('document').ready(function(){
    if ( $('[id^="views_slideshow_cycle_main"]').length > 0 ) {
      var $slider = $('[id^="views_slideshow_cycle_main"]');
      var opts = {
        start: {x: 0, y: 0},
        end: {x: 0, y: 0},
        hdiff: 0,
        vdiff: 0,
        length: 0,
        angle: null,
        direction: null,
      };
      var optsReset = $.extend(true, {}, opts);
      $slider.data('bw', opts);
      $slider.bind('touchstart', function (e) {
        if (e.originalEvent.touches.length == 1) {
          var data = $(this).data('bw');
          data.start.x = e.originalEvent.targetTouches[0].pageX;
          data.start.y = e.originalEvent.targetTouches[0].pageY;
          $(this).data('bw', data);
          //e.preventDefault();
        }
      });
      $slider.bind('touchmove', function (e) {
        var data = $(this).data('bw');
        data.end.x = e.originalEvent.targetTouches[0].pageX;
        data.end.y = e.originalEvent.targetTouches[0].pageY;
        $(this).data('bw', data);
        //e.preventDefault();
      });
      $slider.bind('touchend', function (e) {
        var data = $(this).data('bw');
        if ( data.start.x != 0 && data.start.y != 0 ) {
          data.vdiff = data.start.x - data.end.x;
          data.hdiff = data.end.y - data.start.y;
          var length = Math.round(Math.sqrt(Math.pow(data.vdiff,2) + Math.pow(data.hdiff,2)));
          var rads = Math.atan2(data.hdiff, data.vdiff);
          var angle = Math.round(rads*180/Math.PI);
          if ( angle < 0 ) { angle = 360 - Math.abs(angle); }
          if (length > 300) {
            e.preventDefault();
            if (angle > 135 && angle < 225) {
              var cyopt = $slider.data('cycle.opts');
              if (cyopt.currSlide > 0) {
                $slider.cycle((cyopt.currSlide - 1), 'scrollRight');
              }
              else {
                 $slider.cycle((cyopt.slideCount - 1), 'scrollRight');
              }
            }
            else if (angle > 315 || angle < 45) {
              $slider.cycle('next');
            }
          }
        }
        data = $.extend(true, {}, optsReset);
      });
    }
  });
})( jQuery );
douglasmiller’s picture

I modified the code in comment #9 to allow for click events to work. It has a 0 tolerance for short swipes, but that could be modified fairly easily.
https://gist.github.com/4170907

stewest’s picture

You may also use this plugin for views slideshow in Drupal 7 - http://drupal.org/project/flexslider or see this custom implementation http://www.daymuse.com/blogs/creating-swiping-hero-drupal using the jQuery TouchSwipe plugin.

angrytoast’s picture

I modified the jQuery bindings in #19 above:

  • Included a Modernizr check for touch devices along with the views slideshow element check
  • Changed the pageX / Y for data.end to touchend; the original code seems to miscalculate the X and Y delta if there was no touchmove event
  • Added horizontal and vertical threshold constants to trigger a slider action
(function( $ ) {
  $('document').ready(function(){
    if ( Modernizr.touch && $('.views-slideshow-cycle-main-frame').length ) {
      var $slider = $('.views-slideshow-cycle-main-frame')
          , opts = {
            start: {x: 0, y: 0},
            end: {x: 0, y: 0},
            hdiff: 0,
            vdiff: 0,
            length: 0,
            angle: null,
            direction: null,
          }
          , optsReset = $.extend(true, {}, opts)
          , H_THRESHOLD =  110 // roughly one inch effective resolution on ipad
          , V_THRESHOLD = 50;
          
      $slider.data('bw', opts)
      .bind('touchstart.cycle', function (e) {
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];

        if ( e.originalEvent.touches.length == 1 ) {
          var data = $(this).data('bw');
                    
          data.start.x = touch.pageX;
          data.start.y = touch.pageY;
          $(this).data('bw', data);
          //e.preventDefault();
        }
      })
      .bind('touchend.cycle', function (e) {
          var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
          var data = $(this).data('bw');
          
          data.end.x = touch.pageX;
          data.end.y = touch.pageY;
          $(this).data('bw', data);
        
          if ( data.start.x != 0 && data.start.y != 0 ) {
            data.vdiff = data.start.x - data.end.x;
            data.hdiff = data.end.y - data.start.y;

            if ( Math.abs(data.vdiff) == data.start.x && Math.abs(data.hdiff) == data.start.y ){
              data.vdiff = 0;
              data.hdiff = 0;
            }
            
            var length = Math.round(Math.sqrt(Math.pow(data.vdiff,2) + Math.pow(data.hdiff,2)));
            var rads = Math.atan2(data.hdiff, data.vdiff);
            var angle = Math.round(rads*180/Math.PI);
  
            if ( angle < 0 ) { angle = 360 - Math.abs(angle); }
            
            if (length > H_THRESHOLD && V_THRESHOLD > data.hdiff ) {
              e.preventDefault();
              if (angle > 135 && angle < 225) {
                var cyopt = $slider.data('cycle.opts');
                if (cyopt.currSlide > 0) {
                  $slider.cycle((cyopt.currSlide - 1), 'scrollRight');
                }
                else {
                   $slider.cycle((cyopt.slideCount - 1), 'scrollRight');
                }
              }
              else if (angle > 315 || angle < 45) {
                $slider.cycle('next');
              }
            }
          }

        data = $.extend(true, {}, optsReset);
      });
    }
  });
})( jQuery );
RgnYLDZ’s picture

How do I implement the code in #22 to my site ?

stefan.r’s picture

Issue summary: View changes
FileSize
2.91 KB

This is the code from #22 without the Modernizr dependency

santhoshbabu’s picture

"views_slideshow-974482-23.patch" working fine on iPad
can you someone help me with iphone(same script not working)

shaktik’s picture

NickDickinsonWilde’s picture

Status: Needs review » Fixed

Applied, using @stefan.r's implementation/patch, except put in in the views_slideshow_cycle.js since it is cycle specific rather than just views_slideshow.
Thanks for the discussion and code everyone!

  • NickWilde committed 44f43e0 on 7.x-3.x authored by stefan.r
    Task: Issue #974482 by stefan.r, stovak, angrytoast, argiope: Support '...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.