How To Change Speed Of Gallery Slideshow Squarespace
The following is a guest postal service by Kevin Foley. Kevin is a developer at Squarespace doing absurd stuff with their developer platform, among other things. He was recently working on a swipeable image gallery and he agreed to share some of that work here!
A few weeks ago Chris posted a tutorial for creating a Slider with Sliding Background Images. Around the same time I was working on some new swipeable galleries, and then Chris suggested I write upwardly a tutorial for how to add swipe support to his slider. Here it is!
When creating a swipeable gallery there are 2 techniques — that I know of — you can choose from. You tin animate the scroll position, or move the element using translate
. There are pros and cons to each.
Using Interpret
Moving the slider with interpret
gives you the advantage of hardware acceleration and subpixel animation. Yet, on the initial touch event you might notice a small delay — only a few tens of milliseconds — before the slider starts moving. This isn't very well documented, I've just noticed it in my experience.
Using Overflow Whorl
Overflow whorl is extremely responsive to the initial affect considering it's native to the browser. You don't take to wait for the issue listener in JavaScript. But y'all lose out on all the smoothness of moving elements with interpret.
For this tutorial nosotros're going to use translate
because I retrieve it looks amend.
The HTML
The HTML in this example is going to differ from Chris'south original example. Instead of setting the image as a background image, we're going to gear up it as an element. That will allow u.s.a. to move the epitome to proceeds that absurd panning effect using interpret instead of animating the background position.
<div class="slider-wrap"> <div form="slider" id="slider"> <div course="holder"> <div class="slide-wrapper"> <div form="slide"><img course="slide-prototype" src="//farm8.staticflickr.com/7347/8731666710_34d07e709e_z.jpg" /></div> 74 </div> <div form="slide-wrapper"> <div class="slide"><img class="slide-epitome" src="//farm8.staticflickr.com/7384/8730654121_05bca33388_z.jpg" /></div> 64 </div> <div class="slide-wrapper"> <div class="slide"><img class="slide-epitome" src="//farm8.staticflickr.com/7382/8732044638_9337082fc6_z.jpg" /></div> 82 </div> </div> </div> </div>
The CSS
For the most part the CSS is the same as Chris' and then I won't rehash how to set the layout. But there are a few central differences.
Instead of just adding overflow ringlet, we need to animate the slides. So for that we're going to employ a class to prepare the transition and add it with JavaScript when we need it.
.animate { transition: transform 0.3s ease-out; }
IE ten handles touch events differently than mobile Webkit browsers, like Chrome and Safari. We'll address the Webkit touch events in JavaScript, but in IE10 we tin create this unabridged slider (about) with nothing only CSS.
.ms-bear on.slider { overflow-x: roll; overflow-y: subconscious; -ms-overflow-mode: none; /* Hides the scrollbar. */ -ms-scroll-chaining: none; /* Prevents Metro from swiping to the side by side tab or app. */ -ms-scroll-snap-blazon: mandatory; /* Forces a snap whorl behavior on your images. */ -ms-coil-snap-points-ten: snapInterval(0%, 100%); /* Defines the y and x intervals to snap to when scrolling. */ }
Since these properties are probably new to most people (they were to me, likewise) I'll walk through each 1 and what it does.
-ms-scroll-chaining
The Surface tablet switches browser tabs when y'all swipe across the page, rendering all swipe events useless for developers. Luckily it's really easy to override that behavior by setting scroll chaining to none on any given element.
-ms-ringlet-snap-type
When set to mandatory, this property overrides the browser'south default scrolling behavior and forces a scrollable chemical element to snap to a sure interval.
-ms-coil-snap-points-x
This property sets the intervals the scrollable element will snap to. It accepts 2 numbers: the first number is the starting point; the second is the snap interval. In this example, each slide is the full width of the parent chemical element, which ways the interval should exist 100% — i.e. the element will snap to 100%, 200%, 300%, and and so on.
-ms-overflow-style
This belongings lets you hibernate the scrollbar when you set it to none.
The JavaScript
The first matter we have to do in JavaScript is notice what kind of touch on device we're using. IE 10 uses pointer events while Webkit has "touchstart," "touchmove," and "touchend." Since the IE 10 slider is (almost) all in CSS nosotros need to detect that and add a class to the wrapper.
if (navigator.msMaxTouchPoints) { $('#slider').addClass('ms-touch'); }
Pretty simple. If you tested the slider at this signal it would be a functioning swipeable slideshow. But we still need to add the panning issue on the images.
if (navigator.msMaxTouchPoints) { $('#slider').addClass('ms-bear upon'); // Listed for the roll event and move the image with translate. $('#slider').on('scroll', part() { $('.slide-image').css('transform','translate3d(-' + (100-$(this).scrollLeft()/six) + 'px,0,0)'); }); }
And that'south it for IE 10.
Now for the webkit way. This will all exist wrapped in the else
statement. First we've just got to ascertain a few variables.
else { var slider = { // The elements. el: { slider: $("#slider"), holder: $(".holder"), imgSlide: $(".slide-image") }, // The stuff that makes the slider piece of work. slideWidth: $('#slider').width(), // Summate the slider width. // Ascertain these as global variables then we can use them across the entire script. touchstartx: undefined, touchmovex: undefined, movex: undefined, index: 0, longTouch: undefined, // etc
Then we need to initialize the function and define the events.
// continued init: function() { this.bindUIEvents(); }, bindUIEvents: function() { this.el.holder.on("touchstart", role(consequence) { slider.start(issue); }); this.el.holder.on("touchmove", office(event) { slider.move(event); }); this.el.holder.on("touchend", function(effect) { slider.stop(event); }); },
Now for the fun stuff that actually makes stuff happen when y'all swipe the slider.
Touchstart
On the iPhone (and most other affect sliders) if you motion the slider slowly, just a lilliputian fleck, it will snap back into its original position. Only if yous do information technology quickly information technology will increment to the side by side slide. That fast movement is called a moving-picture show. And at that place isn't any native manner to test for a movie so we've got to use a niggling hack. On touchstart we intitialize a setTimeout function and gear up a variable after a certain amount of time.
this.longTouch = simulated; setTimeout(role() { // Since the root of setTimout is window we tin can't reference this. That's why this variable says window.slider in front of information technology. window.slider.longTouch = true; }, 250);
Nosotros've also got to get the original position of the touch on to make out animation work. If you've never done this before, it's a little strange. JavaScript lets you define multitouch events, then you can pass the touches event a number that represents the amount of fingers yous're listening for. For this instance I'thousand actually only interested in ane finger/thumb and so in the code sample beneath that's what the [0] is for.
// Get the original touch position. this.touchstartx = event.originalEvent.touches[0].pageX;
Before nosotros outset moving the slider I'thou going to remove the animate class. I know there is no animate form on the elements right at present, simply we demand this for the subsequent slides. We'll add information technology dorsum to an element on touchend.
$('.animate').removeClass('breathing');
Touchmove
The touchmove event behaves similarly to coil events in JavaScript. That is, if yous practice something on scroll it's going to execute a bunch of times while the ringlet is occuring. So nosotros're going to get the touchmove position continuously while the finger/thumb is moving.
// Continuously return touch on position. this.touchmovex = event.originalEvent.touches[0].pageX;
Then nosotros'll do a quick calculation using the touchstart position we got in the last event and the touchmove position to figure out how to translate the slide.
// Calculate distance to translate holder. this.movex = this.index*this.slideWidth + (this.touchstartx - this.touchmovex);
Then we need to pan the image, similar Chris did in the original example. We're going to use the same magic numbers he did.
// Defines the speed the images should move at. var panx = 100-this.movex/6;
Now nosotros need to add in some logic to handle edge cases. If you're on the starting time slide or the final slide this logic will stop the image panning if you're scrolling in the wrong direction (i.e. toward no content). This might not be the all-time fashion to handle this, only information technology works for me right now.
if (this.movex < 600) { // Makes the holder terminate moving when there is no more content. this.el.holder.css('transform','translate3d(-' + this.movex + 'px,0,0)'); } if (panx < 100) { // Corrects an edge-case problem where the background prototype moves without the container moving. this.el.imgSlide.css('transform','translate3d(-' + panx + 'px,0,0)'); }
Touchend
In the touchend event nosotros've got to figure out how far the user moved the slide, at what speed, and whether or not that activeness should increment to the next slide.
Outset we need to see exactly how far the distance of the swipe was. We're going to calculate the accented value of the altitude moved to see if the user swiped.
// Calculate the distance swiped. var absMove = Math.abs(this.index*this.slideWidth - this.movex);
At present we're going to figure out if the slider should increment. All the other calculations in this example are based on the alphabetize variable, so this is the real logic behind the script. It checks if the user swiped the minimum distance to increase the slider, or if the movement was a film. And if it meets either of those 2 criteria, which direction did the swipe go in.
// Calculate the alphabetize. All other calculations are based on the alphabetize. if (absMove > this.slideWidth/2 || this.longTouch === faux) { if (this.movex > this.index*this.slideWidth && this.alphabetize < two) { this.index++; } else if (this.movex < this.index*this.slideWidth && this.index > 0) { this.index--; } }
Now we add together the animate form and ready the new translate position.
// Move and animate the elements. this.el.holder.addClass('animate').css('transform', 'translate3d(-' + this.index*this.slideWidth + 'px,0,0)'); this.el.imgSlide.addClass('animate').css('transform', 'translate3d(-' + 100-this.alphabetize*50 + 'px,0,0)');
The Decision
Then, yea, hooray for IE 10.
But seriously, creating swipeable galleries is kind of a pain, considering it's such a common idiom on mobile OS's. And the end issue won't be every bit good as native swiping. But it volition exist close.
Here's the complete demo:
Check out this Pen!
Merely you're best bet is checking it out on your touch device here.
Source: https://css-tricks.com/the-javascript-behind-touch-friendly-sliders/
Posted by: holderbray1962.blogspot.com
0 Response to "How To Change Speed Of Gallery Slideshow Squarespace"
Post a Comment