Skip to content

Instantly share code, notes, and snippets.

@moiseshilario
Created November 7, 2018 18:32
Show Gist options
  • Save moiseshilario/b49bac46746c6be4a9514d0caa961a01 to your computer and use it in GitHub Desktop.
Save moiseshilario/b49bac46746c6be4a9514d0caa961a01 to your computer and use it in GitHub Desktop.
Slide drag animation
// ===================================
// ============ Slide ================
// ===================================
/*
<div class"i-slides">
<div class="i-slide"></div>
<div class="i-slide"></div>
<div class="i-slide"></div>
...
</div>
<div class="i-dots">
<div class="i-dot selected"></div>
<div class="i-dot"></div>
<div class="i-dot"></div>
...
</div>
----------- CSS required -------------
.animate {
transition: all .5s ease-out;
}
*/
$(function() {
var sliding = 0;
var startClientX = 0;
var startPixelOffset = 0;
var pixelOffset = 0;
var currentSlide = 0;
var slideCount = $('.i-slide').length;
var slideWidth = $('.i-slide').outerWidth();
$('html .i-slides')
.on('mousedown touchstart', slideStart)
.on('mouseup touchend', slideEnd)
.on('mousemove touchmove', slide);
/**Triggers when slide event started
*/
function slideStart(event) {
// If it is mobile device redefine event to first touch point
if (event.originalEvent.touches) {
event = event.originalEvent.touches[0];
}
// If sliding not started yet store current touch position to calculate distance in future.
if (sliding === 0) {
sliding = 1; // Status 1 = slide started.
startClientX = event.clientX;
}
}
/** Occurs when slide is being slid.
*/
function slide(event) {
event.preventDefault();
if (event.originalEvent.touches) {
event = event.originalEvent.touches[0];
}
// Distance of slide.
var deltaSlide = event.clientX - startClientX;
// If sliding started first time and there was a distance.
if (sliding === 1 && deltaSlide !== 0) {
sliding = 2; // Set status to 'actually moving'
startPixelOffset = pixelOffset; // Store current offset
}
// When user move slide
if (sliding === 2) {
// Means that user slide 1 pixel for every 1 pixel of mouse movement.
var touchPixelRatio = 1;
// Check for user doesn't slide out of boundaries
if ((currentSlide === 0 && event.clientX > startClientX) ||
(currentSlide === slideCount - 1 && event.clientX < startClientX)) {
// Set ratio to 3 means slide will be moving by 3 pixels each time user moves it's pointer by 1 pixel. (Rubber-band effect)
touchPixelRatio = 3;
}
// Calculate move distance.
pixelOffset = startPixelOffset + deltaSlide / touchPixelRatio;
// Apply moving and remove animation class
$('.i-slides').css('transform', 'translateX(' + pixelOffset + 'px').removeClass('animate');
}
}
/** When user release pointer finish slide moving.
*/
function slideEnd() {
if (sliding === 2) {
// Reset sliding.
sliding = 0;
// Calculate which slide need to be in view.
currentSlide = pixelOffset < startPixelOffset ? currentSlide + 1 : currentSlide - 1;
// Make sure that unexisting slides weren't selected.
currentSlide = Math.min(Math.max(currentSlide, 0), slideCount - 1);
// Since in this example slide is full viewport width offset can be calculated according to it.
pixelOffset = currentSlide * -(slideWidth);
// Remove style from DOM (look below)
$('#temp').remove();
// Add a translate rule dynamically and asign id to it
$('<style id="temp">.i-slides.animate{transform:translateX(' + pixelOffset + 'px)}</style>').appendTo('head');
// Add animate class to slider and reset transform prop of this class.
$('.i-slides').addClass('animate').css('transform', '');
// Change active dot
$('.i-dot.selected').removeClass('selected');
$('.i-dot:eq(' + currentSlide + ')').addClass('selected');
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment