Animating background image relative to mousemove - javascript

So I have an object on a page with a background image and on mousemove it moves the background position relative to the mouse. But the only problem i have is animating the background image to the current position of the mouse when it enters the object.
I am able to animate the background position back to its original position.
Heres my jQuery
//MOUSE MOVE, INVERT BACKGROUND POSITION
jQuery('.homeSlider').mousemove(function(move){
var moveMouse = (move.pageX * -1 / 15);
jQuery('.homeSlider .slide').css({
'background-position-x': moveMouse + 'px'
});
});
//MOUSE LEAVE, ANIMATE BACKGROUND TO START POSITION
jQuery('.homeSlider').mouseleave(function(){
jQuery('.homeSlider .slide').animate({
'background-position-x': '0'
});
});
http://jsfiddle.net/TWHh2/

Add this CSS
.slide {
transition: background-position-x 0.5s;
}
updated fiddle

In addition to using CSS transitions as vals suggested, you could also use JS to either set the position or animate it depending on the distance it needs to be moved. If the distance is above a threshold, you can animate it (otherwise the movement is jumpy). Otherwise, set the CSS as you currently are.
Something like this may work:
var animating = false;
jQuery('.homeSlider').mousemove(function(move){
var $slider = jQuery('.homeSlider .slide');
var moveMouse = (move.pageX * -1 / 3);
var bgPos = $slider.css('background-position-x');
if (!animating && Math.abs(moveMouse - parseInt(bgPos)) > 10) {
animating = true;
$slider.animate({
'background-position-x': moveMouse + 'px'
}, 400);
setTimeout(function() {
animating = false;
}, 400);
} else if (!animating) {
$slider.css({
'background-position-x': moveMouse + 'px'
});
}
});
jsFiddle
I would recommend this over the pure CSS solution because that would always apply the animation, which includes small background position changes. If you check the fiddle with the transition, the smooth background effect is no longer very responsive and loses some of its smoothness.
The downside to this is that it becomes poorly-responsive when the mouse moves quickly, similar to the CSS-only solution.
Alternative
Combine the JS and CSS transition solutions:
CSS
.slide.animate {
transition: background-position-x 0.4s;
}
JS
...
if (!$slider.hasClass('animate') && Math.abs(moveMouse - parseInt(bgPos)) > 10) {
$slider.addClass('animate');
setTimeout(function() {
$slider.removeClass('animate');
}, 400);
}
...

Related

Animate when certain pixels into viewport (Pen by Bramus)

I'm using the following pen by Bramus to animate(FadeInUp) divs when entering the viewport. However currently the div only starts fading in when the div is completely in the viewport. What I need is the flexibility to start the animation when a div is a certain pixels inside the viewport. For example it will start the animation FadeInUp when the div is 100 pixels in the viewport. How can I do this with the current code/pen I'm using (see code below)?
Is this also possible with percentages? F.e. when a div is 20% in viewport the animation starts?
Thanks.
jQuery(function($) {
// Function which adds the 'animated' class to any '.animatable' in view
var doAnimations = function() {
// Calc current offset and get all animatables
var offset = $(window).scrollTop() + $(window).height(),
$animatables = $('.animatable');
// Check all animatables and animate them if necessary
$animatables.each(function(i) {
var $animatable = $(this);
if (($animatable.offset().top + $animatable.height() - 20) < offset) {
$animatable.removeClass('animatable').addClass('animated');
}
});
};
// Hook doAnimations on scroll, and trigger a scroll
$(window).on('scroll', doAnimations);
$(window).trigger('scroll');
});
Offsetting is already foreseen in the code. Tweak the value of 20 in this line:
if (($animatable.offset().top + $animatable.height() - 20) < offset) {
You might also need to change the - sign to a + to suit your needs.

How to animate nested content when animated parent slide moves into viewport, not using scroll

I'm looking to use javascript to animate the content of a nested DIV within an parent slide when the parent slide moves into the viewport.
At the moment, the content in the nested DIV only animates once a scroll command is also triggered after the parent slide moves onto the screen. I believe this is because the slide motion is animated and not scroll controlled.
The same issue is at play in this JSFiddle demo I created to explore the issue:
http://jsfiddle.net/9dz3ubL1/
(The animated movement of the slide from right to left in this demo has been created to test for this problem, to replicate the motion of the slide without scrolling; it is not actually a feature of the development proper).
My question is, how can I script for the animations to be triggered for each nested DIV, when each slide element moves into the viewport, without requiring a scroll function?
Thanks for any help. Here's the script I'm using to control opacity and other CSS stylings.
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll(function() {
/* Reveal hidden_header delayed */
$('.hidden_header').each(function(i) {
var center_of_object = $(this).offset().left + $(this).outerWidth();
var center_of_window = $(window).scrollLeft() + $(window).width();
/* If the object is completely visible in the window, fade it it */
if (center_of_window > center_of_object) {
$(this).animate({
'opacity': '1'
}, 500);
$(this).animate({
'right': '0'
}, 1500);
}
});
/* Reveal hidden_content delayed */
$('.hidden_content').each(function(i) {
var center_of_object = $(this).offset().left + $(this).outerWidth();
var center_of_window = $(window).scrollLeft() + $(window).width();
/* If the object is completely visible in the window, fade it it */
if (center_of_window > center_of_object) {
$(this).animate({
'opacity': '1'
}, 3000);
$(this).animate({
'bottom': '0'
}, 3500);
}
});
/* Reveal button delayed */
$('.button').each(function(i) {
var center_of_object = $(this).offset().left + $(this).outerWidth();
var center_of_window = $(window).scrollLeft() + $(window).width();
/* If the object is completely visible in the window, fade it it */
if (center_of_window > center_of_object) {
$(this).animate({
'opacity': '1'
}, 5000);
}
});
});
});
If your slide motion is animated fully (not incremental as it is in the jsfiddle you linked) then jQuery provides you with the ability to perform an action after your animation is complete.
http://api.jquery.com/animate/
Look at the options you can use for the animation function. One of them is called done. You can assign a function to the done option and that function will be called when your animation is complete.
Using one of your animates as an example, the syntax may look like this:
$(this).animate({
'opacity': '1'
}, {duration: 3000, done: function () {
//animate some stuff here
}};
Note that I just picked a random animation from your code. I'm not sure exactly when you want to perform the animation of the content, but you can use this technique anywhere you use a jQuery animate.
I've used this before to control nested animations in a slideshow format and it has worked very well! I hope this what you wanted.

Scrolling Opacity Shift To and From Targeted Element

I'm trying to get an overlay div's opacity to fade to black as you approach a targeted element in the middle of the page, and then fade back to transparent after that element exits the viewport.
(Broken) Example: https://jsfiddle.net/dtcgbxcn/3/
As you approach the 'blue' section, it should get darker. The page should be solid black before the blue section enters the viewport. Then, after the blue section exits the viewport, it begins to gradually fade out the opacity. By the time you reach the bottom of the page (or another targeted element), the overlay should be fully transparent again.
Note that, due to responsiveness, the height of any of these sections is indeterminate.
$(window).on('scroll', function() {
var st = $(this).scrollTop(),
offset = $('.blue').offset().top - $('.blue').height(),
opacity = st / offset;
_docHeight = $('.red').height() + $('.blue').height() + $('.yellow').height();
$('.overlay').height(_docHeight);
if (opacity > 2) {
opacity = 3 - opacity;
}
$('.overlay').css('opacity', opacity);
});
I have fiddled around with your example, Hopefully this is what you were looking for as far as functionality. It should be 100 opacity right before the blue appears, and 100% clear as the blue comes off the screen. I would prob warp this whole thing in a closure, and cache the selectors so you don't have to call $() every time, but other than that - this should work.
Your fiddle was a little different than your example above - but let me know if this is what you are looking for.
https://jsfiddle.net/gmydzzmf/1/
$(window).on('scroll', function() {
var st = $(this).scrollTop(),
win_height = $(window).height(),
offset = $('.two').offset().top - $('.two').height() - ( win_height / 2),
_docHeight = $('.one').height() + $('.two').height();
if (st<offset ){
// fading in
opacity = st/offset;
} else {
// fading out
opacity = ((_docHeight - st)/(win_height*2));
}
$('.overlay').height(_docHeight); //move this to resize event
$('.overlay').css('opacity', opacity);
});

Click through div and fade out on mouse over

I have a navbar on the top of the page, and when certain events run, I have a header that pops up for about 3 seconds. During this time you cannot click on the underlying nav links.
.alert-header{
pointer-events: none;
}
I tried doing a css transition, but pointer events are set to none. So I tried with jquery (assuming pointer events only affect css):
$(document).on('mouseenter', '.alert-header', function(){
$(this).animate({opacity: 0.2}, 'fast');
}).on('mouseleave', '.alert-header', function(){
$(this).animate({opacity: 1}, 'fast');
});
So, after doing that and testing it, I get the same result as with doing a css transition.
Is there a way where I can fade out the header to 0.2 opacity when the mouse moves over it, and be able to click on the underlying links?
Okay, I have figured out a way. First in the css I turn off pointer events for the div I want to click through:
.alert-header{
pointer-events: none;
}
Next I test the Y position of the mouse when it moves cursor and when the header is visible, if the Y position is less than the height of the header I make it fade, otherwise I fade it back to opaque.
var fadeRunning = false;
$(document).on('mousemove', function(e){
var header = $('.alert-header');
if(header.is(':visible')){
var mouseY = e.pageY;
var height = header.outerHeight();
if(mouseY <= height && !fadeRunning){
fadeRunning = true;
header.animate({opacity: 0.2}, 'fast', function(){fadeRunning=false});
}else{
if(!fadeRunning){
fadeRunning = true;
header.animate({opacity: 1}, 'fast', function(){fadeRunning=false});
}
}
}else{
header.css({opacity: 1});
}
});

Fade element opacity on scroll based off window width

I'm trying to fade in an element based off when it first enters the viewport then have it equal 100% opacity by the time it hits the end of the viewport. I have working as far as reaching 100% opacity when it gets to the end. However, when it starts animating, it starts out at about 60% which I know is because I am basing it off the scroll position. So my question is how can I calculate the opacity starting at 0 once it enters the viewport?
This is what I have so far:
$('.left-cont').each(function() {
var $this = $(this),
leftPos = $this.offset().left,
fadeStart = leftPos - winWidth,
fadeUntil = leftPos,
opacity;
console.log( winWidth - (leftPos - scrollPos));
console.log(fadeStart);
if( scrollPos <= fadeStart ) {
opacity = 0;
}
else {
opacity = scrollPos/fadeUntil;
}
$this.css({
'opacity': opacity
});
});
I can provide more context if needed. Any help is appreciated.
1) Is this jQuery function only executed once or is it placed inside the onScroll-binded function?
$( window ).scroll(function() {
/* get scroll top and left values here */
$( ".box" ).each(function(){
/* do position check and css adjustments here */
});
});
2) The calculation for the opacity is:
(1 - ((box_offsetTop - scrollTop) / windowHeight))
3) I made a working example here for scrolling vertically: http://jsfiddle.net/0mks8eut/1/
You can change it to calculate opacity based on horizontal scrolling by (un)commenting the other calculation inside the function.
! Make sure that there is enough content (or padding/margin) after/next to the object. Otherwise it will never reach opacity:1 (e.g. the top/left of the screen).

Categories

Resources