Skip to content

Instantly share code, notes, and snippets.

@garrows
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garrows/db2364809237fa9cabd4 to your computer and use it in GitHub Desktop.
Save garrows/db2364809237fa9cabd4 to your computer and use it in GitHub Desktop.
Window Pane Slider
<html>
<head>
<title>Slider Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<style>
body {
margin: 0px;
padding: 0px;
}
.slider-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow-x: hidden;
}
.slider {
position: relative;
height: 100%;
transform: translate3d(0px, 0px, 0px);
/*width: 300%; Calculated */
}
.slider>div {
position: absolute;
padding: 0px;
/*width: 33%; Calculated */
height: 100%;
overflow: auto;
overflow-scrolling: touch;
-webkit-overflow-scrolling: touch;
}
</style>
</head>
<body>
<div class="slider-wrapper">
<div class="slider">
<div style="background-color:red">One</div>
<div style="background-color:green">
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
</div>
<div style="background-color:blue">Three
<input type="range" name="points" min="0" max="10">
</div>
</div>
</div>
<script>
//amount of pixels between touch samples to constitute a flick between panels
var FLICK_SPEED = 0;
var HORIZONTAL_ANGLE_THRESHOLD = 20;
var lastClickPosition = null;
var snapTimeout = null;
var swipingHorizontal = false;
var checkHorizontal = false;
var slider = null;
var forceSwipe = false;
var setupPositions = function() {
slider = document.querySelector('.slider');
var panels = slider.children;
slider.style.width = (panels.length * 100) + '%';
//calculate leftmost
var x = -window.innerWidth * ((panels.length - 1) / 2);
for (var i = 0; i < panels.length; i++) {
panels[i].style.WebkitTransform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)';
panels[i].style.transform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)';
panels[i].style.width = Math.round(slider.clientWidth / slider.children.length) + 'px';
x += window.innerWidth;
}
};
window.onload = setupPositions();
window.onresize = setupPositions();
// setupPositions();
var convertClick = function(evt) {
//Handle click or touch.
var source = (evt.touches && evt.touches[0]) || evt;
return {
x: source.clientX,
y: source.clientY
};
};
var mouseMove = function(evt) {
if (evt.which !== 1 && !evt.touches) {
//console.log('resetting');
// lastClickPosition = null;
return true;
}
var pos = convertClick(evt);
if (!lastClickPosition) {
lastClickPosition = pos;
checkHorizontal = true;
return true;
}
pos.dx = lastClickPosition.x - pos.x;
pos.dy = lastClickPosition.y - pos.y;
if (checkHorizontal) {
//Calculate angle of swipe
checkHorizontal = false;
var radians = Math.atan(pos.dy / pos.dx);
var degrees = radians * 180 / Math.PI;
if (degrees < HORIZONTAL_ANGLE_THRESHOLD && degrees > -HORIZONTAL_ANGLE_THRESHOLD) {
swipingHorizontal = true;
}
}
lastClickPosition = pos;
if (swipingHorizontal) {
evt.preventDefault();
} else {
//Dont swipe because we are scrolling
return false;
}
x += pos.dx;
var t = slider.style.transform;
if (!t) {
t = 'translate3d(0px, 0px, 0px)';
}
var x = parseInt(t.substring(t.indexOf('(') + 1, t.indexOf('px')));
x -= pos.dx;
//Make sure it hasnt swiped too far
if (x > slider.clientWidth / (slider.children.length / 2) || x < -slider.clientWidth / (slider.children.length / 2)) {
return;
}
slider.style.WebkitTransform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)';
slider.style.transform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)';
return true;
};
var mouseDown = function(evt) {
lastClickPosition = null;
};
var mouseUp = function() {
if (swipingHorizontal == false) {
lastClickPosition = null;
return;
}
swipingHorizontal = false;
//Check for fast flick to force change of screens
if (lastClickPosition && (lastClickPosition.dx > FLICK_SPEED || lastClickPosition.dx < -FLICK_SPEED)) {
//Flick direction
if (lastClickPosition.dx > 0) {
//right
forceSwipe = -1;
} else {
//left
forceSwipe = 1;
}
}
lastClickPosition = null;
//get its position from the css transform
var t = slider.style.transform;
var x = parseInt(t.substring(t.indexOf('(') + 1, t.indexOf('px')));
//Find the position it needs to snap to.
var closestTargetX = window.innerWidth * (Math.round(x / window.innerWidth));
if (forceSwipe) {
//Make sure it hasnt swiped too far
if (closestTargetX + window.innerWidth * forceSwipe < slider.clientWidth / 2 && closestTargetX + window.innerWidth * forceSwipe > -slider.clientWidth / 2) {
//check if we arent over 50% swipe already
var distanceToTarget = closestTargetX - x;
var isUnderHalfWay = distanceToTarget * forceSwipe < 0;
if (isUnderHalfWay) {
closestTargetX += window.innerWidth * forceSwipe;
}
}
}
var animateToLocation = function() {
var moved = false;
var diff = x - closestTargetX;
//only move in 20% increments
var increment = -(diff * 0.2);
//Does it need to move
if (Math.round(increment) != 0) {
moved = true;
} else {
//last increment, just jump to the location to prevent rounding errors
increment = -diff;
}
x += increment;
slider.style.WebkitTransform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)'
slider.style.transform = 'translate3d(' + Math.round(x) + 'px, 0px, 0px)'
if (moved) {
requestAnimationFrame(animateToLocation);
} else {
forceSwipe = false;
}
};
requestAnimationFrame(animateToLocation);
}
document.body.addEventListener("mousemove", mouseMove, false);
document.body.addEventListener("touchmove", mouseMove, false);
document.body.addEventListener("touchstart", mouseDown, false);
document.body.addEventListener("mousedown", mouseDown, false);
document.body.addEventListener("touchend", mouseUp, false);
document.body.addEventListener("mouseup", mouseUp, false);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment