Limit vertical background position on scrolling with jQuery - javascript

I'm using this function:
$(window).bind('load resize scroll',function(e) {
var y = $(window).scrollTop();
$('.tm-parallax').filter(function() {
return $(this).offset().top < (y + $(window).height()) &&
$(this).offset().top + $(this).height() > y;
}).css('background-position', '50% ' + parseInt(-y / 50) + 'px');
});
to achieve parallax effect on background images when scrolling down.
I would like to limit y position to certain value (for example 100px), so background image center stays visible after reaching this value.
Here is the code: http://jsfiddle.net/esedic/vw2n16r8/4/
Because bakcground images are quite large it's best seen on fullscreen: https://jsfiddle.net/esedic/vw2n16r8/4/embedded/result/
Because I'm using parallax background images on multiple elements, I'm looking for solution to set different values for each element (maybe using data attributes?).
Thanks for your help!

You should try reversing its polarity, but try this:
$(window).bind('load resize scroll',function(e) {
var y = $(window).scrollTop();
$('.tm-parallax').filter(function() {
if have return $(this).onset().top < (y + $(window).height()) &&
$(this).onset().top + $(this).height() > y;
}).css('background-position', '50% ' + parseInt(-y / 50) + 'px');
});

Related

Dynamic bottom value based on element position in browser

I am attempting to adapt this JS solution to keep a floating element above the footer of my site.
The adaption I am attempting is instead of changing the element position to absolute, I would have a dynamic bottom px value based on the position of the top of the footer, relevant to the client window.
function checkOffset() {
var onlineFloat = document.querySelector('#online-ceo');
var footer = document.querySelector('.site-footer');
function getRectTop(el){
var rect = el.getBoundingClientRect();
return rect.top;
}
if((getRectTop(onlineFloat) + document.body.scrollTop) + onlineFloat.offsetHeight >= (getRectTop(footer) + document.body.scrollTop) - 20)
var newBottom = ((getRectTop(footer) + document.body.scrollTop) - 40).toString().concat('px');
onlineFloat.style.bottom = newBottom;
if(document.body.scrollTop + window.innerHeight < (getRectTop(footer) + document.body.scrollTop))
onlineFloat.style.bottom = '20px';// restore when you scroll up
}
document.addEventListener("scroll", function(){
checkOffset();
});
The output of newBottom is currently a px value which changes on scroll, however, I am having issues setting this position to the element.
Where am I going wrong? Thanks.
With your approach (changing the bottom property), you can just calculate where the "float" should be if the footer's top position is in view (as in window.innerHeight) on scroll.
function checkOffset() {
var onlineFloat = document.querySelector('#online-ceo');
var footer = document.querySelector('.site-footer');
function getRectTop(el) {
var rect = el.getBoundingClientRect();
return rect.top;
}
var newBottom = 10 + (getRectTop(footer) < window.innerHeight ? window.innerHeight - getRectTop(footer) : 0) + 'px';
onlineFloat.style.bottom = newBottom;
}
document.addEventListener("scroll", function () {
checkOffset();
});

Stop moving background image after a certain X position is reached

I have a section (#intro) with a background image that has horizontal movement on scroll.
$(window).bind("load resize scroll",function(e) {
var y = $(window).scrollTop();
$("#intro").filter(function() {
return $(this).offset().top < (y + $(window).height()) &&
$(this).offset().top + $(this).height() > y;
}).css('background-position', + parseInt(+y / 10) + '% 50%'); ));
What I would like to happen is the background position to move until 80% is met for the X position; at which point the number will not increase. I want the stopping point to be '80% 50%', but if a user scrolls back up it will count down again.
How can I achieve this?

Page scrolling is not smooth when using parallax and animations

This is my first project related with Parallax effects. I have tried to implement parallax libraries but they are not working properly on mac safari, scrolling is not smooth. So i tried to implement custom code which i found on google and its working better than libraries but still scrolling is not smooth. Major scroll effect on mac safari.
Note:- Website is made in PHP, single page website with parallax and animations (wow.js) on page scroll. There are large content on the website, all are images implemented into "section" tags. So there are almost 10 different "section" tags on the page, contains approx. 10 images per "section" tag. Page size is more than 45 MB (with 2 videos playing of 22 MB in size).
Tried solution:- Before that all the images was in PNG format, then i had converted them to JPG format and compressed them also. All images are in higher resolution, out of them some are even 2500*1800. Four different parallax images on different "sections", one parallax image on one "section".
Current Parallax script i am using:-
var scrolled = $(window).scrollTop()
$('.parallax').each(function(index) {
var imageSrc = $(this).data('image-src')
var imageHeight = $(this).data('height')
$(this).css('background-image','url(' + imageSrc + ')')
$(this).css('height', imageHeight)
var initY = $(this).offset().top
var height = $(this).height()
var diff = scrolled - initY
var ratio = Math.round((diff / height) * 100)
$(this).css('background-position','center ' + parseInt(-(ratio * 1.5)) + 'px')
})
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
$('.parallax').each(function(index, element) {
var initY = $(this).offset().top;
var height = $(this).height();
var endY = initY + $(this).height();
var visible = isInViewport(this);
if(visible) {
var diff = scrolled - initY;
var ratio = Math.round((diff / height) * 100);
$(this).css('background-position','center ' + parseInt(-(ratio * 1.5)) + 'px');
}
});
});
function isInViewport(node) {
var rect = node.getBoundingClientRect();
return (
(rect.height > 0 || rect.width > 0) &&
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
);
}
Anyone, please help!

Go to a specific anchor after page resizes (height change only)

I have a one-page website with several anchors (signifying div positions). After the page is resized (change in height only), I want to refresh the page. Then I want to scroll to the anchor the page was previously at, making the window.top position equal to the anchor position. I have javascript for the resize and refresh portion of this (below), but I'm at a loss regarding the scroll portion. Any ideas? How would I check which div the page was on before resizing? "#markerAbout" is one of the anchors.
var height = $(window).height();
var resizeTimer;
$(window).resize(function(){
if($(this).height() != height){
height = $(this).height();
window.location.reload();
//$(window).scrollTop()=$('#markerAbout').offset().top;
}
});
You can find out which of your elements are currently visible on the view port by following the advice in this question:
How to tell if a DOM element is visible in the current viewport?
You will have to do this on each element in the order you expect them to appear until you find one that is visible. That should be the current element at the top of the viewport.
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
Once you know which of your divs are showing and which are not, you can choose which one you want to scroll too.
Once you know which div to scroll to for example Div1, you can call scrollIntoView() on that element.
Div1.scrollIntoView();
Since you refresh the page, setting a variable is out of the table. My suggestion is to reload the page with a reference of the anchor as hash at the end plus add a function which is fired first thing after page load that check if there's a hash in the url and if so scrolls the page to the anchor wrote in the hash. I added also a function that starts the reloading process after the end of the resizing process only and also another one that iterates through all the anchors (you have to add a class="anchors" to each anchor) and defines which is the one visible.
That's the code, hope it helps:
$(document).ready(function(){
if(window.location.hash){
//Scroll to $(window.location.hash)
}
var height = $(window).height();
var resizeTimer;
$.fn.isOnScreen = function(){
var win = $(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
if($(this).height() != height){
height = $(this).height();
anchor = false;
$('.anchors').each(function(){
if($(this).isOnScreen()){
anchor = $(this).attr('id')
return
}
});
window.location.href = window.location.href + anchor;
window.location.reload(true);
}
});});

fixing elements whilst scrolling?

So, I have a div which I'm trying to keep 100px from the top of the page between to points of the page whilst scrolling. At the moment, my code works-ish but the div is not kept at exactly 100px from the top, instead altering between 0px - 200px
here's what I'm using atm:
$(window).scroll(function(){
var tpxl = $(window).scrollTop();
if( tpxl<100) {
$('#div').css('top',-Math.abs(tpxl)+100 + 'px');
}
else if(tpxl>700) {
$('#div').css('top',-Math.abs(tpxl)+800 + 'px');
}
});
You don't need Math.abs() because tpxl will always be a positive number. To set the position of the div to be 100px from the current top of the window, use $(window).scrollTop() + 100 + 'px'.
I don't really understand why you have the if / else if structure. The following would keep the div fixed at 100px all the time:
$(window).scroll(function () {
$('#div').css('top', $(window).scrollTop() + 100 + 'px');
}).scroll();
Demo: http://jsfiddle.net/G5BVU/
To only set the position "fixed" when the scroll point is less than 100 or more than 700 like for your original code try this:
$(window).scroll(function () {
var tpxl = $(window).scrollTop();
if (tpxl < 100 || tpxl > 700) {
$('#div').css('top', tpxl + 100 + 'px');
}
}).scroll();
Demo: http://jsfiddle.net/G5BVU/1/
EDIT: To have the element scroll normally except when the window is scrolled between those two points just reverse the if condition from my previous example:
if (tpxl > 100 && tpxl < 700)
$('#div').css('top', tpxl + 100 + 'px');
http://jsfiddle.net/G5BVU/2/
In all cases provide an initial top setting as appropriate.

Categories

Resources