This may well have been asked before but I have an issue with a parallax effect I have deployed on an image slider. On scroll, the background images being used in the slider adjust their position and their opacity.
The problem is if I scroll a short way down the page and then refresh the page, the background position and the opacity revert to their original values, so then scrolling causes a jump in order for them 'catch up' on what their actual values should be.
I'm trying to figure out how I can have the values automatically set no matter what position the page is in when it's refreshed.
Here is the code that I have currently
//HomepageParallaxFade
window.addEventListener('scroll', function () {
var scrollPosition = window.pageYOffset;
var bgParallax = document.getElementsByClassName('carousel-cell');
Array.prototype.forEach.call(bgParallax, function (el) {
var limit = el.offsetTop + el.offsetHeight;
if (scrollPosition > el.offsetTop && scrollPosition <= limit) {
el.style.backgroundPositionY = (50 + 90 * scrollPosition / limit) + '%';
el.style.opacity = (1 - 1 * scrollPosition / limit);
} else {
el.style.backgroundPositionY = '50%';
}
})
});
Happy to provide a JSFiddle if necessary. All help much appreciated
You can do parallax with pure css.
https://www.digitalocean.com/community/tutorials/css-pure-css-parallax.
From there, when you refresh if you set the scroll position with javascript, the parallax will just work.
Related
I am working on a project, here: https://github.com/erinreiss/spaceship1/tree/ministory1
And I am looking to make a div#landing to go from opacity:1 to opacity:0 within 200 pixels of scrolling, based on scroll position. I was able to do it successfully like this:
var target = $('#landing');
var targetHeight = 200;
$(document).scroll(function(e){
var scrollPercent = (targetHeight - window.scrollY) / targetHeight;
if(scrollPercent >= 0){
target.css('opacity', scrollPercent);
}
});
Now, I want to use waypoints to trigger this same effect but at a different time. I want instead of it firing as the div#landing moves out of the viewport, it instead fires as a defined Waypoint (in this case, a different div#intro1) is scrolled past.
This is my attempt:
var target = $('#landing');
var targetHeight = 200;
var intro1 = $('#intro1').waypoint(function (direction) {
console.log('bam!');
$(document).scroll(function(e){
var scrollPercent = (targetHeight - window.scrollY) / targetHeight;
if(scrollPercent >= 0){
target.css('opacity', scrollPercent);
}
})
}, {offset: 200});
The waypoint fires, but (alas) the scrolling opacity changer does not work...
Any advice? Thank you!!
ps - The other thread with this question is answered with code no longer available :(
How do I animate on scroll inside a waypoint function?
I didn't solve this problem, but I did hack something together close to what I wanted... It allows me to use the scroll position of an overflow element to trigger and define the level of opacity on another element.
See solution here:
https://github.com/erinreiss/spaceship1/tree/ministory1
var target = $('#intro1inner');
$('#intro1inner').scroll(function(){
//define a variable that will be how much the target has scrolled from its original position
var changeA = target.scrollTop()
console.log('changeA:' + changeA)
// I want my change in opacity (from 0-1 to take place over 250px)
var scrollPercent = changeA / 250;
console.log('scrollPercent:' + scrollPercent)
});
I'm using a precoded Parallax JQuery as part of a Wordpress theme called Parallax by Studiopress. It works fairly well, but I end up missing the top half of the image when scrolling and I'd like the user to be able to see that as well when they scroll down. Currently, the background-position starts at "50% 0px" and the px goes into negative figures when you scroll the page. I figure if I set it to start at 200 or 300px the majority of the image can be viewed. However, I can't set the CSS as that gets overridden by JQuery.
I'm fairly new to JQuery so I'm wondering if there's any pointers or method that can be given to help me?
This is the code :
jQuery(function ($) {
// Enable parallax and fade effects on homepage sections
$(window).scroll(function () {
scrolltop = $(window).scrollTop()
scrollwindow = scrolltop + $(window).height();
$(".home-section-2").css("backgroundPosition", "50% " + -(scrolltop / 6) + "px");
if ($(".home-section-4").length) {
sectionthreeoffset = $(".home-section-4").offset().top;
if (scrollwindow > sectionthreeoffset) {
// Enable parallax effect
backgroundscroll = scrollwindow - sectionthreeoffset;
$(".home-section-4").css("backgroundPosition", "50% " + -(backgroundscroll / 6) + "px");
}
}
})
});
For the top image - change scrolltop to scrolltop = $(window).scrollTop() + -1000 The larger the number makes the starting px larger as well.
Every other image requires a duplicate of scrolltop called scrolltop2 which does not contain the number. This is referred to in scrollwindow.
scrolltop2 = $(window).scrollTop()
scrollwindow = scrolltop2 + $(window).height();
Then add the number to backgroundscroll
eg: backgroundscroll = scrollwindow - sectionthreeoffset + -1500;
I wanted to achieve an effect like this http://www.offset.com/
as you can see when it scrolls it slowly covering the carousel rather than scrolling with it.
I've tried using background fixed but the problem is the elements inside it will not stay in its position
Maybe there is a good technique in achieving this, Thanks
this is called parallax scrolling here is an example of how to do this using Jquery :
Live Demo
// Y axis scroll speed
var velocity = 0.5;
function update(){
var pos = $(window).scrollTop();
$('.container').each(function() {
var $element = $(this);
// subtract some from the height b/c of the padding
var height = $element.height()-18;
$(this).css('backgroundPosition', '50% ' + Math.round((height - pos) * velocity) + 'px');
});
};
$(window).bind('scroll', update);
an other example it might help DEMO
NIm creating an animation that moves a div incrementally on scroll. I'm close but I don't think my code is the most efficient and I don't know how to adapt it to add more arguments. So for instance, hitting a certain height on the page will then move the object right and stop moving it down. Below is my JS and the codepen can be found at;
http://codepen.io/anon/pen/KxHwu - Original
http://codepen.io/anon/pen/DLxqg - Messing about with moving right
var lastScrollTop = 0;
var boxPosition = $('#box').position();
var row2Position = $('#row2').position();
var distance = $('#row2').offset().top,
$window = $(window);
console.log(distance);
$window.scroll(function() {
if ( $window.scrollTop() >= distance - 400 ) {
var st = $(window).scrollTop();
console.log(st);
$('#box').css({top: 0 + st});
//CODE NOT WORKING
if(st >= 270) {
var boxPos = $('#box').position();
console.log(boxPos.left);
$('#box').css({left: boxPos.left + st});
}
//
lastScrollTop = st;
}
});
I'm looking for the box to start scrolling like it does, then when it hits half of row 2 scroll right.
I hope I have explained this in an easy way!
Thanks
http://codepen.io/anon/pen/tHwlq
Here is an example of how to do it; you'll need to tweak the numbers to make it work as you plan.
var $window = $(window);
var $box = $("#box");
$window.scroll(function() {
var scrollTop = $window.scrollTop();
if (scrollTop >= 250 && scrollTop < 400) {
$box.css({top: -250 + scrollTop});
} else if(scrollTop >= 400 && scrollTop < 600) {
$box.css({left: (50+(scrollTop-400)/2)+"%"})
}
});
If your project has numerous elements like this, I'd recommend the ScrollMagic (http://janpaepke.github.io/ScrollMagic/) library.
As far as efficiency is concerned I'd recommend the following:
1) Cache the jQuery selectors (note $box variable). Otherwise, jQuery will have to query the DOM on every scroll event.
2) Cache scrollTop rather then querying it multiple times within the event callback.
3) Although left and top work, using the transform: translate() property is more efficient, especially on mobile devices. (https://developer.mozilla.org/en-US/docs/Web/CSS/transform). However, on most mobile devices, scroll events only fire at the completion of a scroll, not while a page is scrolling.
I am trying to get a div to scroll up at the same amount of pixels as the user scrolls down the page. For example, in Google Chrome when using the mouse wheel, it scrolls down in about 20px intervals. But when you scroll down using the handle, the scrolling amount varies.
Here is my code so far:
var scrollCtr = 50;
$(window).scroll(function(){
scrollCtr = scrollCtr - 20;
$('div.nexus-files').css('margin-top', scrollCtr + 'px');
});
There are a few problems with this:
The user scrolling varies
It needs to subtract from margin-top if scrolling down and add to margin-top if scrolling up
Here is an example:
http://www.enflick.com/
Thanks for the help
You're doing it the wrong way, what you are trying to do should be done using position: fixed on div.nexus-files
div.nexus-files{position: fixed; top: 0;}
but anyway - if you still want to know what you can do with the scroll event - you better get to scrollTop of the document and set the margin-top to the same value
window.onscroll = function(event){
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);
document.getElementById('nexus-files_id').style.marginTop = top+'px';
}
I'm using pure Javascript instead of jQuery because of the overhead that might be crucial when the browser need to calculate stuff in a very short amount of time (during the scrolling). [this can be done even more efficient by storing reference to the element and the doc... but you know..)
I used id based selector to get the specific element instead of class based
AND I SAY AGAIN - this is not how you should do what you were trying to do
Why not using the actual scroll offset as reference or position ?
// or whatever offset you need
var scrollOffset = document.body.scrollTop + 20;
// jQuery
var scrollOffset = $("body").scrollTop() + 20;
Finally Got it
Here is the code I used to accomplish the task.
Most of the code is from http://enflick.com and I modified it to work with my individual situation.
jQuery(window).load(function(){
initParallax();
});
// parallax init
function initParallax(){
var win = jQuery(window);
var wrapper = jQuery('#wrapper');
var bg1 = wrapper.find('.nexus-files');
var koeff = 0.55;
if (bg1.length) {
function refreshPosition(){
var scrolled = win.scrollTop();
var maxOffsetY1 = 450;
var offsetY1 = scrolled * koeff;
var offsetY2 = scrolled * koeff - (maxOffsetY1 * koeff - offsetY1);
if (offsetY1 <= maxOffsetY1 * koeff - offsetY1) {
bg1.css("margin-top", +-offsetY1+"px");
//alert(+-offsetY1+"px");
}
}
refreshPosition();
win.bind('resize scroll', refreshPosition);
}
}