I attempted to add a swiping function to my slider to allow users to swipe through the images on their touchable devices. It hasn't turned out the best. When swiping at the images they do not slide over all of the way and then when I get to the end of the gallery (end of fourth image), the slider goes blank (goes white) and then it goes back to normal after a while.
I have added the important code to this question, as well as added a Fiddle to try it out.
The fiddle doesn't replicate the issue, so if you would like to see what this is doing, please go here to see it live. Scroll about halfway down and then you will see the slider.
The example I used had three images instead of four and I am thinking this may be my issue, but when I remove my 4th image (a repeat of the first image for a smoother transition back to the first), the issue is still present. I'm 99% sure the issue resides within the javascript, but I can't locate it.
Does anyone see what I am doing wrong or how to improve this?
Please note. I am putting the full code for this function, but I believe the issue resides within the move or end function here:
move: function(event) {
// Continuously return touch position.
this.touchmovex = event.originalEvent.touches[0].pageX;
// Calculate distance to translate figure.
this.movex = this.index*this.slideWidth + (this.touchstartx - this.touchmovex);
// Defines the speed the images should move at.
var panx = 100-this.movex/6; // was /6
if (this.movex < 600) { // Makes the figure stop moving when there is no more content.
this.el.figure.css('transform','translate3d(-' + this.movex + 'px,0,0)');
}
if (panx < 100) { // Corrects an edge-case problem where the background image moves without the container moving.
this.el.imgSlide.css('transform','translate3d(-' + panx + 'px,0,0)');
}
},
end: function(event) {
// Calculate the distance swiped.
var absMove = Math.abs(this.index*this.slideWidth - this.movex);
// Calculate the index. All other calculations are based on the index.
if (absMove > this.slideWidth/2 || this.longTouch === false) {
if (this.movex > this.index*this.slideWidth && this.index < 2) {
this.index++;
} else if (this.movex < this.index*this.slideWidth && this.index > 0) {
this.index--;
}
}
// Move and animate the elements.
this.el.figure.addClass('animate').css('transform', 'translate3d(-' + this.index*this.slideWidth + 'px,0,0)');
this.el.imgSlide.addClass('animate').css('transform', 'translate3d(-' + 100-this.index*50 + 'px,0,0)');
Full code:
if (navigator.msMaxTouchPoints) {
$('#slider').addClass('ms-touch');
$('#slider').on('scroll', function() {
$('.slide-image').css('transform','translate3d(-' + (100-$(this).scrollLeft()/6) + 'px,0,0)');
});
} else {
var slider = {
el: {
slider: $("#slider"),
figure: $(".figure"),
imgSlide: $(".slide-image")
},
slideWidth: $('#slider').width(),
touchstartx: undefined,
touchmovex: undefined,
movex: undefined,
index: 0,
longTouch: undefined,
init: function() {
this.bindUIEvents();
},
bindUIEvents: function() {
this.el.figure.on("touchstart", function(event) {
slider.start(event);
});
this.el.figure.on("touchmove", function(event) {
slider.move(event);
});
this.el.figure.on("touchend", function(event) {
slider.end(event);
});
},
start: function(event) {
// Test for flick.
this.longTouch = false;
setTimeout(function() {
window.slider.longTouch = true;
}, 250);
// Get the original touch position.
this.touchstartx = event.originalEvent.touches[0].pageX;
// The movement gets all janky if there's a transition on the elements.
$('.animate').removeClass('animate');
},
move: function(event) {
// Continuously return touch position.
this.touchmovex = event.originalEvent.touches[0].pageX;
// Calculate distance to translate figure.
this.movex = this.index*this.slideWidth + (this.touchstartx - this.touchmovex);
// Defines the speed the images should move at.
var panx = 100-this.movex/6; // was /6
if (this.movex < 600) { // Makes the figure stop moving when there is no more content.
this.el.figure.css('transform','translate3d(-' + this.movex + 'px,0,0)');
}
if (panx < 100) { // Corrects an edge-case problem where the background image moves without the container moving.
this.el.imgSlide.css('transform','translate3d(-' + panx + 'px,0,0)');
}
},
end: function(event) {
// Calculate the distance swiped.
var absMove = Math.abs(this.index*this.slideWidth - this.movex);
// Calculate the index. All other calculations are based on the index.
if (absMove > this.slideWidth/2 || this.longTouch === false) {
if (this.movex > this.index*this.slideWidth && this.index < 2) {
this.index++;
} else if (this.movex < this.index*this.slideWidth && this.index > 0) {
this.index--;
}
}
// Move and animate the elements.
this.el.figure.addClass('animate').css('transform', 'translate3d(-' + this.index*this.slideWidth + 'px,0,0)');
this.el.imgSlide.addClass('animate').css('transform', 'translate3d(-' + 100-this.index*50 + 'px,0,0)');
}
};
slider.init();
}
.animate {
transition: transform 0.3s ease-out;
}
#company-slider-section {
width: 100%;
height: auto;
position: relative;
}
div#slider {
width: 100%;
overflow: hidden;
position: relative;
}
div#slider .figure {
position: relative;
width: 400%;
margin: 0;
padding: 0;
font-size: 0;
text-align: left;
}
.ms-touch.slider {
overflow-x: scroll;
overflow-y: hidden;
-ms-overflow-style: none;
/* Hides the scrollbar. */
-ms-scroll-chaining: none;
/* Prevents Metro from swiping to the next tab or app. */
-ms-scroll-snap-type: mandatory;
/* Forces a snap scroll behavior on your images. */
-ms-scroll-snap-points-x: snapInterval(0%, 100%);
/* Defines the y and x intervals to snap to when scrolling. */
}
.figure2 {
animation: 20s company-slider infinite;
margin: 0;
}
#keyframes company-slider {
0% {
left: 0%;
}
30% {
left: 0%;
}
35% {
left: -100%;
}
55% {
left: -100%;
}
60% {
left: -200%;
}
90% {
left: -200%;
}
95% {
left: -300%;
}
100% {
left: -300%;
}
}
.slide-wrapper img {
width: 25%;
min-height: 100%;
float: left;
position: relative;
overflow: hidden;
}
.slide {
height: 100%;
position: relative;
}
.slide:before {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
width: 100%;
height: 40%;
background: linear-gradient(transparent, black);
}
<div id="company-slider-section">
<div class="section-blocks left">
<div id="slider" class="slider">
<figure class="figure figure2">
<div class="slide-wrapper">
<div class="slide"><img src="/images/work/projects/eslich/es-test1.jpg" alt class="slide-image"></div>
</div>
<div class="slide-wrapper">
<div class="slide"><img src="/images/work/projects//desktop-service.jpg" alt class="slide-image"></div>
</div>
<div class="slide-wrapper">
<div class="slide"><img src="/images/work/projects//es-test2.jpg" alt class="slide-image"></div>
</div>
<div class="slide-wrapper">
<div class="slide"><img src="/images/work/projects//es-test1.jpg" alt class="slide-image"></div>
</div>
</figure>
</div>
</div>
</div>
Related
I'm trying to put mouse enter/mouse-leave events on moving elements. There is a problem in handling the hover event with CSS, so I'm trying to process it with JS. This works fine in chrome but not working in safari. How to make mouseenter/mouseleave work properly when the mouse is stopped?
CSS
.big-box {
position: relative;
width: 500px;
height: 100px;
background: #ee9;
}
.hit-box {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: #e99;
}
HTML
<div class="big-box">
<div class="hit-box">hit-box</div>
</div>
JavaScript
const hitbox = document.querySelector('.hit-box');
var position = 5;
hitbox.style.left = 0;
hitbox.addEventListener('mouseenter', function() {
console.log('enter');
});
hitbox.addEventListener('mouseleave', function() {
console.log('leave');
});
setInterval(function() {
if(parseInt(hitbox.style.left) + position > 400) {
position = -5;
} else if(parseInt(hitbox.style.left) + position < 0) {
position= 5;
}
hitbox.style.left = parseInt(hitbox.style.left) + position + 'px';
},20)
I create a SVG blur effect on my page sections. You can see in below snippet. However, my CPU is overloaded and overheating my laptop when I scroll several times. I check complex animation websites without this problem. What's my problem? Is there a problem with my codes?
$(window).on('load', function() {
$('.blurred-bg').each(function(index, value) {
var filterName = $(this).attr('id') + 'filtering';
$(this).prepend(
'<svg class="svgs" xmlns="http://www.w3.org/2000/svg" version="1.1" height="0"><filter id="' + filterName + '"><feGaussianBlur result="blur"></feGaussianBlur><feMorphology in="blur" operator="dilate" radius="15" result="expanded"/><feMerge><feMergeNode in="expanded"/><feMergeNode in="blur"/></feMerge></filter></svg>'
);
});
$(window).scroll(function(e) {
var distanceScrolled = $(this).scrollTop();
$('.blurred-bg').each(function(index, value) {
var distanceElementTop = ($(this).offset().top);
if (distanceScrolled < distanceElementTop) {
$(('svg.svgs filter feGaussianBlur'), this)[0].setAttribute("stdDeviation", '0');
} else if (distanceScrolled > distanceElementTop) {
var elmHeight = $(this).height();
var sub = elmHeight / 10;
var result = ((distanceScrolled - distanceElementTop) / sub);
if (result >= 0 && result <= 10) {
$(('svg.svgs filter feGaussianBlur'), this)[0].setAttribute("stdDeviation", result);
}
}
});
});
});
section {
position: relative;
width: 100%;
height: 100vh;
background-size: cover;
background-attachment: fixed;
background-repeat: no-repeat;
overflow-x: hidden;
overflow-y: auto;
}
section:before {
background: inherit;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
}
#first {
background-image: url('https://freephotos.cc/storage/path/1Sujr0vCiT0cQpjbMgmdzAIjtdfEq2lF3bq4U1oo.jpeg');
}
#first:before {
-webkit-filter: url(#firstfiltering);
filter: url(#firstfiltering);
}
#two {
background-image: url('https://freephotos.cc/storage/path/c1haICnHGYIyRK2juLs36iEBoBiJMOarzSQ9CKRv.jpeg');
}
#two:before {
-webkit-filter: url(#twofiltering);
filter: url(#twofiltering);
}
#three {
background-image: url('https://freephotos.cc/storage/path/OpgzqCRPTnxQ5z22gNvNgiF7ZSTzNyPXtXKwVwS4.jpeg');
}
#three:before {
-webkit-filter: url(#threefiltering);
filter: url(#threefiltering);
}
.svgs,
.svg-section {
position: absolute;
width: 0;
height: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="first" class="blurred-bg"></section>
<section id="two" class="blurred-bg"></section>
<section id="three" class="blurred-bg"></section>
https://codepen.io/mehrdadam/pen/NyexLa
UPDATE:
I test this without SVG filter and remove jQuery and set blur filter for section. My CPU overloaded on view of blurred section!
Constantly recalcuating blurs is extremely CPU intensive. A better way to do this is to overlay a highly blurred, transparent copy of the image on top of the original and gradually increase its opacity as you scroll down.
So I have a set of elements called .project-slide, one after the other. Some of these will have the .colour-change class, IF they do have this class they will change the background colour of the .background element when they come into view. This is what I've got so far: https://codepen.io/neal_fletcher/pen/eGmmvJ
But I'm looking to achieve something like this: http://studio.institute/clients/nike/
Scroll through the page to see the background change. So in my case what I'd want is that when a .colour-change was coming into view it would slowly animate the opacity in of the .background element, then slowly animate the opacity out as I scroll past it (animating on scroll that is).
Any suggestions on how I could achieve that would be greatly appreciated!
HTML:
<div class="project-slide fullscreen">
SLIDE ONE
</div>
<div class="project-slide fullscreen">
SLIDE TWO
</div>
<div class="project-slide fullscreen colour-change" data-bg="#EA8D02">
SLIDE THREE
</div>
<div class="project-slide fullscreen">
SLIDE TWO
</div>
<div class="project-slide fullscreen colour-change" data-bg="#cccccc">
SLIDE THREE
</div>
</div>
jQuery:
$(window).on('scroll', function () {
$('.project-slide').each(function() {
if ($(window).scrollTop() >= $(this).offset().top - ($(window).height() / 2)) {
if($(this).hasClass('colour-change')) {
var bgCol = $(this).attr('data-bg');
$('.background').css('background-color', bgCol);
} else {
}
} else {
}
});
});
Set some data-gb-color with RGB values like 255,0,0…
Calculate the currently tracked element in-viewport-height.
than get the 0..1 value of the inViewport element height and use it as the Alpha channel for the RGB color:
/**
* inViewport jQuery plugin by Roko C.B.
* http://stackoverflow.com/a/26831113/383904
* Returns a callback function with an argument holding
* the current amount of px an element is visible in viewport
* (The min returned value is 0 (element outside of viewport)
*/
;
(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var elH = $(el).outerHeight(),
H = $(win).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? Math.min(elH, H - t) : (b < H ? b : H)), H);
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
// OK. Let's do it
var $wrap = $(".background");
$("[data-bg-color]").inViewport(function(px, winH) {
var opacity = (px - winH) / winH + 1;
if (opacity <= 0) return; // Ignore if value is 0
$wrap.css({background: "rgba(" + this.dataset.bgColor + ", " + opacity + ")"});
});
/*QuickReset*/*{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}
.project-slide {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.project-slide h2 {
font-weight: 100;
font-size: 10vw;
}
<div class="project-slides-wrap background">
<div class="project-slide">
<h2>when in trouble...</h2>
</div>
<div class="project-slide" data-bg-color="0,200,255">
<h2>real trouble...</h2>
</div>
<div class="project-slide">
<h2>ask...</h2>
</div>
<div class="project-slide" data-bg-color="244,128,36">
<h2>stack<b>overflow</b></h2>
</div>
</div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
Looks like that effect is using two fixed divs so if you need something simple like that you can do it like this:
But if you need something more complicated use #Roko's answer.
var fixed = $(".fixed");
var fixed2 = $(".fixed2");
$( window ).scroll(function() {
var top = $( window ).scrollTop();
var opacity = (top)/300;
if( opacity > 1 )
opacity = 1;
fixed.css("opacity",opacity);
if( fixed.css('opacity') == 1 ) {
top = 0;
opacity = (top += $( window ).scrollTop()-400)/300;
if( opacity > 1 )
opacity = 1;
fixed2.css("opacity",opacity);
}
});
.fixed{
display: block;
width: 100%;
height: 200px;
background: blue;
position: fixed;
top: 0px;
left: 0px;
color: #FFF;
padding: 0px;
margin: 0px;
opacity: 0;
}
.fixed2{
display: block;
width: 100%;
height: 200px;
background: red;
position: fixed;
top: 0px;
left: 0px;
color: #FFF;
padding: 0px;
margin: 0px;
opacity: 0;
}
.container{
display: inline-block;
width: 100%;
height: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
Scroll me!!
</div>
<div class="fixed">
</div>
<div class="fixed2">
</div>
I am fairly new to writing in html, css, and coding in javascript.
I digress; i am trying to have an image of a gear rotate when the a user scrolls up and down the screen (i am hoping to give it an elevator effect when i add a belt).
I am using the jquery $(window).scroll(function(). I know it is working because when i use console.log("hi") it writes every time i scroll. My problem is the .animate() function that doesn't seem to work. I even tried downloading "http://jqueryrotate.com/" and using that to rotate.
Any help would be much appreciated!
## HTML ##
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>
## CSS ##
.left_pulley
{
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img
{
width: 100%;
}
.right_pulley
{
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img
{
width: 100%;
}
## JS ##
First using .rotate({})
$(".left_pulley").rotate({bind:
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
$(.left_pulley).rotate({
angle: 0,
animateTo: 180,
})
})
})
})
Now using .animate({}) to try and just move it at all.
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
var scott = $('img');
scott.animate({
left: 180
}
}
});
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
var scott = $('img');
scott.animate({
left: 180
}
function() {
console.log("hi");
}
});
console.log("hi2");
}
});
.left_pulley {
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img {
width: 100%;
}
.right_pulley {
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img {
width: 100%;
}
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>
[
picture of gears i want to rotate.
]1
You should look into the CSS3 transform property, more specifically the rotate() function. Here
It would also be beneficial to add a transistion property to create an animated 'tween' between rotation values. Here. Make sure to add this transition to the transition property (as this is where rotation is set).\
You can then change the rotation of the gear (with automatic animation!) using jquery by setting the css value of the transition property, for example:
#gear{
transition: transform 300ms;
transform: rotate(7deg);
transform-origin:90% 90%;
position:absolute;
left:100px;
top:100px;
font-size:10rem;
width:100px;
height:100px;
}
You can test it out here by hitting run.
https://jsfiddle.net/oc4hhons/
Borrowing heavily from https://stackoverflow.com/a/17348698/2026508
You could do something like this:
var degrees = 0;
var prevScroll = 0;
$(window).scroll(function() {
if ($(window).scrollTop() > 0) {
if (prevScroll > $(window).scrollTop()) {
$('.woo').css({
'-webkit-transform': 'rotate(' + degrees+++'deg)',
'-moz-transform': 'rotate(' + degrees+++'deg)',
'-ms-transform': 'rotate(' + degrees+++'deg)',
'transform': 'rotate(' + degrees+++'deg)'
});
console.log('prevScroll greater:', prevScroll)
} else if (prevScroll < $(window).scrollTop()) {
$('.woo').css({
'-webkit-transform': 'rotate(' + degrees--+'deg)',
'-moz-transform': 'rotate(' + degrees--+'deg)',
'-ms-transform': 'rotate(' + degrees--+'deg)',
'transform': 'rotate(' + degrees--+'deg)'
});
console.log('prevScroll less:', prevScroll)
}
prevScroll = $(window).scrollTop()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height: 40px; width: 100px;background-image: url(' gear2.png ');background-color:blue;" class="woo">turn</div>
JS Fiddle-Updated, now they rotate together same direction but the rotation is depending on whether the scroll is up or down:
JS:
var $gears = $('.gear'),
$i = 0,
$scrollBefore = 0;
$(window).scroll(function () {
if($(this).scrollTop() > $scrollBefore){
$scrollBefore = $(this).scrollTop();
$gears.css("transform", "rotate(" + ($i+=4) + "deg)");
}else if($(this).scrollTop() < $scrollBefore){
$scrollBefore = $(this).scrollTop();
$gears.css("transform", "rotate(" + ($i-=4) + "deg)");
}
});
this JS Fiddle 2, makes them rotate in opposite directions, and each gear direction switches depending if the scrolling is up or down:
JS:
var $gearLeft = $('.left_pulley'),
$gearRight = $('.right_pulley'),
$i = 0,
$j = 0,
$scrollBefore = 0;
$(window).scroll(function() {
if ($(this).scrollTop() > $scrollBefore) {
$scrollBefore = $(this).scrollTop();
$gearLeft.css("transform", "rotate(" + ($i += 4) + "deg)");
$gearRight.css("transform", "rotate(" + ($j -= 4) + "deg)");
} else if ($(this).scrollTop() < $scrollBefore) {
$scrollBefore = $(this).scrollTop();
$gearLeft.css("transform", "rotate(" + ($i -= 4) + "deg)");
$gearRight.css("transform", "rotate(" + ($j += 4) + "deg)");
}
});
Thanks for all the help everyone!
Just want to post my finial code in case anyone else needs help in the future.
/* Scott Louzon 11/24/15
This code is used to rotate two images of a gears when user scrolls */
/*This function see's when user scrolls then calls rotate_right & rotate_left
accordingly */
var scroll_at = 0; //variable to keep track of
//scroll postion
$(window).scroll(function() {
if ($(this).scrollTop() > 0) //if scroll postion is not at
{ //top do this
if ($(this).scrollTop() > scroll_at) //if scroll postion is > than b4
{
rotate_down();
}
else if ($(this).scrollTop() < scroll_at) //if scroll postion is < than b4
{
rotate_up();
}
scroll_at = $(this).scrollTop(); //set varible to were scroll
//postion is at now
}
})
//Both these functions call css to rotate the image of a gear
var rotation = 0;
function rotate_down()
{
rotation+= 8;
$(".left_pulley").css("transform","rotate("+ rotation +"deg)");
$(".right_pulley").css("transform","rotate("+ (-1 * rotation) +"deg)");
}
function rotate_up()
{
rotation += 8;
$(".left_pulley").css("transform","rotate("+ (-1 * rotation)+"deg)");
$(".right_pulley").css("transform","rotate("+ rotation +"deg)");
}
.left_pulley
{
position: absolute;
margin: 0;
padding: 0;
/*Used for gear rotation */
transition: transform 1ms;
transform-origin:50% 50%;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img
{
width: 100%;
}
.right_pulley
{
position: absolute;
margin: 0;
padding: 0;
/* Used for gear rotation */
transition: transform 1ms;
transform-origin:50% 50%;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img
{
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>
After studying, looking at tutorials, getting some help here, I almost got this script working as intended. However, I'm not at a stand still and my brain hurts trying to figure out the logic.
The problem is the script allows for over scrolling forward. How can I stop that?
jQuery:
var $item = $('.slider'),
start = 0,
view = $('#main-header').width(),
end = $('.slider').width();
$('.next').click(function () {
if (start < view) {
start++;
$item.animate({
'left': '-=100%'
});
}
});
$('.prev').click(function () {
if (start > 0) {
start--;
$item.animate({
'left': '+=100%'
});
}
});
HTML:
<div id="main-header">
<div class="slider">
<div class="item-post" style="background: url(http://4.bp.blogspot.com/-LjJWOy7K-Q0/VOUJbMJr0_I/AAAAAAAAdAg/I2V70xea8YE/s320-c/enviroment-5.jpg) center"></div>
<div class="item-post" style="background: url(http://1.bp.blogspot.com/-l3UnbspFvv0/VOUK8M-34UI/AAAAAAAAdA0/ooGyXrHdNcg/s320-c/enviroment-2.jpg)"></div>
<div class="item-post" style="background: url(http://2.bp.blogspot.com/-cun1kQ42IBs/VOUaSPfnebI/AAAAAAAAdBQ/yTEj9K-BGdk/s320-c/fashion-3.jpg)"></div>
</div>
<div class="prev"></div>
<div class="next"></div>
</div>
CSS:
#main-header {
overflow: hidden;
position: relative;
}
.slider {
width: 100%;
height: 200px;
position: relative;
}
.item-post {
width: 100%;
height: 200px;
background: rgba(0, 0, 0, 0.1);
background-size: cover !important;
background-position: center !important;
position: absolute;
top: 0;
}
.item-post:first-of-type {
left: 0;
}
.item-post:nth-of-type(2) {
left: 100%;
}
.item-post:last-of-type {
left: 200%;
}
.prev, .next {
position: absolute;
top: 0;
bottom: 0;
width: 25px;
background: rgba(0, 0, 0, 0.2);
cursor: pointer;
}
.prev {
left: 0;
}
.next {
right: 0;
}
jsfiddle: http://jsfiddle.net/51maaks8/8/
In order to determine whether there is another slide visible, you could create a function that adds the .offsetLeft value of the parent element to the .offsetLeft value of the last visible slide element and its width. You would then subtract the width of the parent element from the sum of these calculations.
In doing so, you are essentially calculating the position of the last slide element relative to the left positioning of the .item-wrapper parent element.
function moreVisibleSlides() {
var $last = $('#slider > .item-wrapper > .item-post:last:visible'),
positionRelativeToParent = $last.parent()[0].offsetLeft + $last[0].offsetLeft + $last.width() - $item.width();
return positionRelativeToParent > 5;
}
For the click event listener, only slide the element if there are more visible slides, which is determined by the boolean returned by the moreVisibleSlides function. In addition, I also added a check (!$item.is(':animated')) to prevent the next slide from being animated if there is currently an animation in progress. This ensures that you can't click the .next button multiple times during an animation and then over scroll regardless of whether or not there are more visible slides.
Updated Example
$('.next').click(function () {
if (moreVisibleSlides() && !$item.is(':animated')) {
start++;
$item.animate({
'left': '-=100%'
});
}
});