jQuery curtain scroller app - javascript

I'm trying to build a curtain slider - much like what is used on the Apple site - http://www.apple.com/30-years/
http://jsfiddle.net/NYEaX/405/
I've created the following code - I need to add listeners to detect the mouse hovering over the far left/far right sides of the page - and then invoke an exponential slide.
var curtainSlider = {
invoke: function(el){
var that = this;
var list = $(el + " ul").find("li");
this.initialListWidth = list.outerWidth(true);
list
.mouseover(function() {
console.log("over");
that.expand(this);
})
.mouseout(function() {
console.log("out");
that.contract(this);
});
},
expand: function(el){
var that = this;
$(el).stop().animate({
width: that.initialListWidth*2
},400, function() {
// Animation complete.
});
},
contract: function(el){
var that = this;
$(el).stop().animate({
width: that.initialListWidth
},400, function() {
// Animation complete.
});
}
}
$(document).ready(function() {
console.log( "ready!" );
curtainSlider.invoke("#curtain");
});

**LATEST CODE - complete integration - http://jsfiddle.net/NYEaX/538/ **
I have stabilized this version of the scroller. - This curtains the images and spectrum fades them on start up. It repositions the a elements so the image is more centrally aligned.
http://jsfiddle.net/NYEaX/432/
I've separated out the code responsible for moving the slider unit, with an acceleration/deceleration. Its this part of the application I wish to focus on now.
http://jsfiddle.net/NYEaX/434/
I've tried to push the pagex variable into the animation part to help manipulate the duration of the animation. How can this be stabilized/improved on. I am finding it hard to reverse engineer the apple 30 year slider.
var curtainSlider = {
bindEvents: function(){
var that = this;
$("body").on("mousemove",function(event) {
if (event.pageX < 50) {
// animate curtain left
console.log("curtain left");
that.scroll("l", event.pageX);
}
if (event.pageX > (window.width - 50)) {
// animate curtain right
console.log("curtain right");
that.scroll("r", window.width - event.pageX);
}
});
},
scroll: function(direction, leveler){
var charge = "-";
if(direction == "r"){
charge = "+";
}
$('#curtainholder #slider').animate({
left: charge+"="+leveler
},400, function() {
// Animation complete.
});
},
invoke: function(el){
var that = this;
this.bindEvents();
}
}
$(document).ready(function() {
curtainSlider.invoke("#curtain");
});

Related

Jquery - How to loop this slider?

So I've been working on a slider and I don't really know how to make it repeat itself. So far I've only listed 10 slides but in the end I'll have around 20.
Here's a link to a JS fiddle so you can see what I've got so far:
https://jsfiddle.net/sth23e2w/
$(document).ready(function() {
//settings for slider
var width = 360;
var animationSpeed = 1000;
var pause = 3000;
var currentSlide = 1;
//cache DOM elements
var $slider = $(".characters");
var $slideContainer = $(".slide-characters", $slider);
var $slides = $(".char-avatar", $slider);
$(".right-slide").click(function() {
$slideContainer.animate(
{ "margin-left": "+=" + width },
animationSpeed,
function() {
if (++currentSlide === $slides.length) {
currentSlide = 1;
$slideContainer.css("margin-left", 0);
}
}
);
});
$(".left-slide").click(function() {
$slideContainer.animate(
{ "margin-left": "-=" + width },
animationSpeed,
function() {
if (++currentSlide === $slides.length) {
currentSlide = 1;
$slideContainer.css("margin-left", 0);
}
}
);
});
});
Or if you really want you could check out the live version I've got over at Codepen: https://codepen.io/Crownedpride/project/editor/ZmbqRv/
If you want to know what it's going to be used for:
I'm currently writing a fantasy novel which I've got an artist drawing characters for. I want to display those characters on my own website via that setup I've made. There's roughly going to be 20 different characters that he'going to draw for me, although later there might be more depending if there'll be a Volume 2.
I'm looking forward to your replies.
ps: I'm really new to Jquery/js so please go easy on me >_<

Elements reverting back to original sizes after JQuery animation

So I am trying to get my header to change its size to become smaller after the user scrolls a certain distance down the page, the animations for the header to get bigger and smaller execute at the right time. Only issue is on the animation to make the header bigger, the animation happens as it should but as soon as it has finished animated the header reverts back to its original size for some reason. Not sure if this makes any difference but the header has its position set to fixed in the css. I have never come across an issue like this so have no idea what is going wrong, and googling it hasn't helped me either.
You can view the issue here: http://eventrem.com
Full Javascript:
function getScrollOffsets() {
var doc = document, w = window;
var x, y, docEl;
if ( typeof w.pageYOffset === 'number' ) {
x = w.pageXOffset;
y = w.pageYOffset;
} else {
docEl = (doc.compatMode && doc.compatMode === 'CSS1Compat')?
doc.documentElement: doc.body;
x = docEl.scrollLeft;
y = docEl.scrollTop;
}
return {x:x, y:y};
}
var IsHeaderBig;
window.onload = function() {
var offset = getScrollOffsets();
if (offset.y > 100) {
IsHeaderBig = false;
animateHeaderSmall(0);
} else {
IsHeaderBig = true;
animateHeaderBig(0);
}
}
window.addEventListener('scroll', function(){
var offset = getScrollOffsets();
if (offset.y > 100) {
//Make Small
if (IsHeaderBig) {
IsHeaderBig = false;
animateHeaderSmall(300);
}
} else {
//Make Big
if (!IsHeaderBig) {
IsHeaderBig = true;
animateHeaderBig(300);
}
}
});
function animateHeaderBig(speed) {
var header = $("#headerContainer");
var buffer = $("#homeBuffer");
header.animate({
height:'548px'
}, speed, function() {});
buffer.animate({
height:'470px'
}, speed, function() {});
}
function animateHeaderSmall(speed) {
var header = $("#headerContainer");
var buffer = $("#homeBuffer");
header.animate({
height:'100px'
}, speed, function() {});
buffer.animate({
height:'100px'
}, speed, function() {});
}
The easy solution is to handle the complete function and set the values there.
function animateHeaderBig(speed) {
var header = $("#headerContainer");
var buffer = $("#homeBuffer");
header.animate({
height:'548px'
}, {
duration: speed,
complete: function() {
$(this).css('height', '548px');
}
});
buffer.animate({
height:'470px'
}, {
duration: speed,
complete: function() {
$(this).css('height', '470px');
}
});

IE9 Defaulting to IE7, javascript bug

I have this javascript that seems to be forcing IE9 into computability mode and forcing it to IE7. There are other areas of the website working properly that do not have this javascript code working on them, which leads me to believe something in this script is not compatible with IE9/IE7.
Basically, the code creates a pop up box when your mouse hovers over it. However if the pop up box displays over an image, the image shows through the pop up box as if it has precedence. I have tried changing the z-index on that div but no luck.
Any suggestions?
jQuery('.bubbleInfo').each(function () {
if(jQuery.trim(jQuery(this).find('#dpop').html()) != ''){ // start
var totalHeight = jQuery(this).height();
var distance = 15;
var time = 250;
var hideDelay = 150;
var hideDelayTimer = null;
var beingShown = false;
var shown = false;
var trigger = jQuery('.trigger', this);
var info = jQuery('.popup', this).css('opacity', 0);
jQuery([trigger.get(0), info.get(0)]).mouseover(function () {
if (hideDelayTimer) clearTimeout(hideDelayTimer);
if (beingShown || shown) {
// don't trigger the animation again
return;
} else {
// reset position of info box
beingShown = true;
info.css({
top: (totalHeight+38),
left: -77,
display: 'block'd
}).animate({
top: '-=' + distance + 'px',
opacity: 1
}, time, 'swing', function() {
beingShown = false;
shown = true;
});
}
return false;
}).mouseout(function () {
if (hideDelayTimer) clearTimeout(hideDelayTimer);
hideDelayTimer = setTimeout(function () {
hideDelayTimer = null;
info.animate({
top: '-=' + distance + 'px',
opacity: 0
}, time, 'swing', function () {
shown = false;
info.css('display', 'none');
});
}, hideDelay);
return false;
});
} // end
IE < 10 have issue in the jquery library version although IE10 supports all the version's of jquery.

jQuery function losing the called elements and only keeping the last caller

I am developing a parallax site, and I want to ease out the elements when the scrolling has stopped. So I developed a plugin to detect when the scrolling stops, and once it stops, then smooth out the movement of the element (The object moves 5 pixels on to the direction in which the user was scrolling). It works but only to the last element that the plugin was applied to. When i was trying to debug, I see that both elements are still in effect inside the $(window).scroll(function(event) { but once we reach $(window).scrollStopped(function(){ only the last element is in effect. Any solutions?
// Scroll Direction set
var lastScrollTop = 0, scrollDirection = "";
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
scrollDirection = "down";
} else {
scrollDirection = "up";
}
lastScrollTop = st;
});
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,250,self));
});
};
// Smooth ending
$.fn.smoothStop = function () {
var $this = $(this);
$(window).scroll(function(event) {
$(window).scrollStopped(function(){
var top = parseFloat($this.css("top"));
if(scrollDirection == "down")
{
console.log(top, $this);
var new_top = top + 5;
$this.animate({
top: new_top + 'px'},
1000);
}
else{
var new_top = top - 5;
$this.animate({
top: new_top + 'px'},
1000);
}
});
});
};
$(".g6").smoothStop();
$(".g2").smoothStop();
JSFIDDLE
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){ <-- this is the window
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout')); <----timeout is removed from window
}
$this.data('scrollTimeout', setTimeout(callback,250,self)); <----timeout is set to window
});
};
basically you are trying to run multiple events, but you end up storing those multiple events in the same memory location. So when you add a new one, it cancells out the previous entry.

javascript 'over-clicking' bug

I have a bug in Javascript where I am animating the margin left property of a parent container to show its child divs in a sort of next/previous fashion. Problem is if clicking 'next' at a high frequency the if statement seems to be ignored (i.e. only works if click, wait for animation, then click again) :
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
//roll margin back to 0
}
An example can be seen on jsFiddle - http://jsfiddle.net/ZQg5V/
Any help would be appreciated.
Try the below code which will basically check if the container is being animated just return from the function.
Working demo
$next.click(function (e) {
e.preventDefault();
if($contain.is(":animated")){
return;
}
var marLeft = $contain.css('margin-left'),
$this = $(this);
if (marLeft === (-combinedWidth + (regWidth) + "px")) {
$contain.animate({
marginLeft: 0
}, function () {
$back.fadeOut('fast');
});
} else {
$back.fadeIn(function () {
$contain.animate({
marginLeft: "-=" + regWidth + "px"
});
});
}
if (marLeft > -combinedWidth) {
$contain.animate({
marginLeft: 0
});
}
});
Sometimes is better if you create a function to take care of the animation, instead of writting animation code on every event handler (next, back). Also, users won't have to wait for the animation to finish in order to go the nth page/box.
Maybe this will help you:
if (jQuery) {
var $next = $(".next"),
$back = $(".back"),
$box = $(".box"),
regWidth = $box.width(),
$contain = $(".wrap")
len = $box.length;
var combinedWidth = regWidth*len;
$contain.width(combinedWidth);
var currentBox = 0; // Keeps track of current box
var goTo = function(n) {
$contain.animate({
marginLeft: -n*regWidth
}, {
queue: false, // We don't want animations to queue
duration: 600
});
if (n == 0) $back.fadeOut('fast');
else $back.fadeIn('fast');
currentBox = n;
};
$next.click(function(e) {
e.preventDefault();
var go = currentBox + 1;
if (go >= len) go = 0; // Index based, instead of margin based...
goTo(go);
});
$back.click(function(e) {
e.preventDefault();
var go = currentBox - 1;
if (go <= 0) go = 0; //In case back is pressed while fading...
goTo(go);
});
}
Here's an updated version of your jsFiddle: http://jsfiddle.net/victmo/ZQg5V/5/
Cheers!
Use a variable to track if the animation is taking place. Pseudocode:
var animating = false;
function myAnimation() {
if (animating) return;
animating = true;
$(this).animate({what:'ever'}, function() {
animating = false;
});
}
Crude, but it should give you the idea.
Edit: Your current code works fine for me as well, even if I jam out on the button. On firefox.

Categories

Resources