I have the following code to make some parallax niceness which is mapped to the scroll bar.
It moves both the background position of the section and any elements in the section classed "mover"
It works fine with jQuery 1.4.x but when we upgraded to 1.5.2 the elements don't quite get back to their original positions
Does anyone know what changes in 1.5 would cause this?
var lastScrollTop = 0
var scrollTop = 0
$(window).scroll(function() {
scrollTop = $(window).scrollTop();
var move = lastScrollTop - scrollTop;
lastScrollTop = scrollTop;
$('.mover').each(function(i, element){
element = $(element);
if(!belowTheFold(element)){
var currentPos = parseInt(element.css("top"));
var speed = $(this).attr('data-scroll-speed');
var pos = currentPos + (move*speed);
element.css('top', pos);
}
});
$('.background-mover').each(function(i,element){
element = $(element);
if(!belowTheFold(element)){
var currentPos = parseInt(element.css("background-position-y"));
var speed = element.attr('data-scroll-speed');
var pos = currentPos + (move*speed);
element.css('background-position-y', pos);
}
});
});
function belowTheFold(element){
var fold = $(window).height() + $(window).scrollTop();
return fold <= element.offset().top;
}
HTML:
<section class="background-mover" data-scroll-speed="0.1" style="background:url(images/background.jpg) no-repeat; /*background-size:cover;*/ ">
Places
Nature
Landscape
Adventure
</section>
<section class="background-mover" data-scroll-speed="0.2" style="background:url('images/background-2.jpg') no-repeat; height:630px; ">
Getting Around
Events
Accomodation
</section>
<section class="background-mover" data-scroll-speed="0" style="background:url(images/background-3.jpg) no-repeat; /*background-size:cover;*/ height:1200px; ">
Culture
Must Do's
Getting Here
History
Facts
</section>
Related
I'm trying to implement an animation that switches images on scroll when it's wrapping div scrolls into the viewport. My problem is that the animation starts as soon as someone starts scrolling, so the animation is already at the end when #wrapper comes into viewport.
How to achieve that the animation starts when #wrapper scrolls into the viewport?
Unfortunately my JS/jQuery knowledge is very poor but this is what I got til now:
JSFiddle
HTML:
<div class="page_content_before_image_animation">
<p>lorem ipsum …</p>
</div>
<div id="load" data-images="19"></div>
<div id="wrapper">
<img class="sequenzbilder" src="https://twdp.de/sequence/1.jpg" width="600" height="661" />
</div>
JS:
var images = [];
for (i = 1; i <= $('#load').attr('data-images'); i++) {
images.push('https://twdp.de/sequence/' + i + '.jpg');
}
$(images).each(function() {
$('<img class="sequenzbilder" />')[0].src = this;
});
var totalImages = images.length;
var pageHeight = $(document).height() - $(window).height();
var scrollInterval = Math.floor(pageHeight / 140);
var viewport = $(window),
slowdown;
viewport.on('scroll', function() {
i = Math.floor($(this).scrollTop() / scrollInterval);
$('.sequenzbilder').attr('src', images[i]);
slowdown = Math.ceil(viewport.scrollTop() / 20);
});
I'm working on a progress bar animation which needs to animate from 0 to whatever percentage when the progress bar becomes visible within browser's viewport. Animation should always happen when element is scrolled into the view which means that scrolling it outside has to reset animation to start.
Here's my non-working code:
var $animation_elements = $('.progressAnimation');
var $window = $(window);
function check_if_in_view() {
var window_height = $window.height();
var window_top_position = $window.scrollTop();
var window_bottom_position = (window_top_position + window_height);
$.each($animation_elements, function() {
var $element = $(this);
var element_height = $element.outerHeight();
var element_top_position = $element.offset().top;
var element_bottom_position = (element_top_position + element_height);
//check to see if this current container is within viewport
if ((element_bottom_position >= window_top_position) &&
(element_top_position <= window_bottom_position)) {
$element.animate({
"width": (600 * $($element).data("percent")) / 100
}, 3000);
} else {
$element.animate({
"width": "0"
}, 1000)
}
});
}
$window.on('scroll resize', check_if_in_view);
$window.trigger('scroll');
body{
height:4000px;
margin-top:800px;
}
.myContainer{
width:1000px;
margin:50px auto;
}
.myContainer .progressBackground{
width:600px;
height:40px;
margin:0 auto 40px;
background-color:#eaeaea;
}
.myContainer .progressAnimation{
width:0;
height:100%;
background-color:#00f36d;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myContainer">
<div class="progressBackground">
<div class="progressAnimation" data-percent="80">
</div>
</div>
<div class="progressBackground">
<div class="progressAnimation" data-percent="60">
</div>
</div>
</div>
Note: run code snippet in fullscreen.
Animating using Javascript within scroll/resize event isn't really wise. Without throttling the event it is wiser to do something very simple.
I haven't delved into your code and why it doesn't work, but I've devised an example based on your code, but I'm doing animation using CSS (offloading animation off of browser process), and simply changing elements' state when it's different from what it should be. This means that I'm shrinking progress bar to 0 only when element goes off screen (and not every single time a scroll/resize event fires which is what you're doing) and animating progress bar when it comes on screen only when it's been off screen.
This is the code:
var $animation_elements = $('.progressAnimation');
$(window).on('scroll resize', function(){
var viewportHeight = document.documentElement.clientHeight;
$animation_elements.each(function() {
var $el = $(this);
var position = this.getBoundingClientRect();
if (position.top > viewportHeight || position.bottom < 0) {
this.inView && $el.css({ width: 0 });
this.inView = false;
} else {
!this.inView && $el.css({ width: 6 * $el.data("percent") });
this.inView = true;
}
});
});
As you can see I've also used as much vanilla Javascript as possible to make event handler as fast as possible.
And here is a working JSFiddle.
I am trying to implement a sidebar to follow the user's screen as he or she scrolls up or down in the browser page. However I am getting an issue where the sidebar continues to scroll down the page infinitely if the user keeps scrolling down.
var element = $('#movingBox'),
originalY = element.offset().top;
// Space between element and top of screen (when scrolling)
var topMargin = 100;
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < originalY
? 0
: scrollTop - originalY + topMargin
}, 300);
});
Is there a way to limit the sidebar from scrolling too far down than its supposed to?
I hope I have understood your question. You want to stop the box following at a certain position like this ?
var element = $('#movingBox'),
originalY = element.offset().top;
// Space between element and top of screen (when scrolling)
var topMargin = 100;
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
var stop = $('#stop').offset().top; // or in pixel
stop -= $('#movingBox').height() + topMargin;
if (scrollTop<stop) {
element.stop(false, false).animate({
top: scrollTop < originalY
? 0
: scrollTop - originalY + topMargin
}, 300);
}
});
Try the example in JSFiddle
I'm trying to move an element to left and right while scrolling up and down in this example FIDDLE the problem is the div will keep moving to reach out of the page and doesn't return to its original position. This is the example I'm trying to simulate Original Example
HTML
<div class='container'>
<div class='inner'>
</div>
</div>
JS
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
var offset = $(".inner").offset();
var w = $(window);
var x = offset.left;
console.log(x);
$(".inner").css("left",x+50);
} else {
var offset = $(".inner").offset();
var w = $(window);
var y = offset.left;
console.log(y);
$(".inner").css("left",y-50);
}
lastScrollTop = st;
});
CSS
.container{width:100%; position: relative; float:left; background:#fff; height:1200px;}
.inner{width:150px; height:100px; position:absolute; top:20%; left:10%; background:red;}
You need to offset it by the scrolled amount, not move it by an amount each time. You are queuing up multiple moves and adding 50px each time.
var offset = $(".inner").offset();
$(window).scroll(function(event) {
var st = $(this).scrollTop();
$(".inner").css("left", st + offset.left);
});
JSFiddle: https://jsfiddle.net/TrueBlueAussie/x0vtopzv/1/
Once it is locked to the scrolling, you can adjust the position using a multiplier on the st value.
Note: JSFiddle has an 8px margin on the body. That throws out the offset position and needs to be removed or taken into account.
https://jsfiddle.net/TrueBlueAussie/x0vtopzv/6/
I'm using jquery.parallax-1.1.3.js for a parallax effect. (site: http://ianlunn.co.uk/plugins/jquery-parallax/)
Problem: it works with css background-position. This works for background images but not for text in my html.
What I want: add some code to this js file that allows me to use the parallax effect on html text (H1, H2). I prefer with an ID. So a H1 would have a div around it with an ID that is connected with the parallax effect.
This is the js:
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
This is how to call the js from html:
<script type="text/javascript" src="js/jquery.parallax-1.1.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//.parallax(xPosition, speedFactor, outerHeight) options:
//xPosition - Horizontal position of the element
//inertia - speed to move relative to vertical scroll. Example: 0.1 is one tenth the speed of scrolling, 2 is twice the speed of scrolling
//outerHeight (true/false) - Whether or not jQuery should use it's outerHeight option to determine when a section is in the viewport
$('#third').parallax("50%", 0.5);
})
</script>
You give a div an ID. You give this Div a background-image. You connect the ID to the parallax effect above. I want to do the same, but then with an H1.