How to avoid the "blink" when exchanging gifs? - javascript

I am creating a website where when you scroll into an area, a gif appears. It only loops once; if you continue scrolling, it changes to another gif (which plays only once, too) If you scroll back, it changes to the first gif, restarting it so it can play again.
However, when the changing occurs, there is a blink that I do not want. Here is the fiddle. And here is the javascript:
$(window).ready(function() {
var v = 0;
$(window).on("scroll", function() {
var scrollTop = $(this).scrollTop();
if (scrollTop > 100 && scrollTop < 200) {
if ($('#container').attr('data-img') != 'http://i.imgur.com/Hhmt8.gif') {
++v;
$('#container').attr('data-img', 'http://i.imgur.com/Hhmt8.gif');
$('#container').css('background-image', 'url(http://i.imgur.com/Hhmt8.gif?v=' + v + ')');
}
} else if (scrollTop >= 200) {
if ($('#container').attr('data-img') != 'http://i.imgur.com/TUAwA.gif') {
++v;
$('#container').attr('data-img', 'http://i.imgur.com/TUAwA.gif');
$('#container').css('background-image', 'url(http://i.imgur.com/TUAwA.gif?v=' + v + ')');
}
} else {
$('.imageHolder').css('background', 'blue');
}
});
});
I tried removing the ?v='+v+' from the background-image but then it won't load everytime it changes... Is there a way to keep the functioning as it is without the blinking?

Preload the second image, the blinking comes from the remote fetching time of the image. If you had preloaded the same image at any point on this website before, the new image will be loaded directly from the browser's cache and will replace the previous one without any visible transition.
$(window).ready(function () {
var v = 0;
var image = new Image();
image.src = 'http://i.imgur.com/TUAwA.gif';
$(window).on("scroll", function () {
/* ... */
}
}

Related

jQuery fails to set the width of a div on first load

I'm working on a site for my friend, where the fixed footer should have a margin of the size of the big picture (that's used as a menu). I also want the content div to have the same margin. But for some reason when I first load the page, content div and the footer don't have any margin at all. When I re-load the page, everything works perfectly... But I want it to work on the initial loading of the page. Here's my code:
$(document).ready(function(){
var mainPicWidth = $('#navimg').width();
var mainPicWidth2 = mainPicWidth - 10;
$('#footer').css('margin-left', mainPicWidth2)
$('#content').css('margin-left', mainPicWidth)
var wholePageWidth = $('#content').width() + 15;
$('#footer').css('width', wholePageWidth)
I also have the follow part as means of making the site responsive. Could this conflict with my previous code somehow?
$(window).bind('resize', function(e) {
if (window.RT) clearTimeout(window.RT);
window.RT = setTimeout(function() {
this.location.reload(false); /* false to get page from cache */
}, 100);
});
if ($(window).width() <= 1100) {
$('#footer').css('width', "100%")
$('#footer').css('margin-left', "0")
$('#content').css('margin-left', "0")
});
}
if ($(document.body).height() != $("*").height()) {
$('#footer').css('position', 'fixed')
$('#footer').css('bottom', '0')
} else {
$('#footer').css('position', 'relative')
}

Hide social links when scrolling over certain images like on medium.com

I have medium and large images on a page and when my social links show up over these images I want to fade out the social links and fade back in when they are off the images. The amount of medium and large images will vary per page. You can see it working on a Medium.com post.
https://blog.fullstory.com/assess-customer-frustration-with-fullstory-rage-grade-497cf7b7aba1
The code below works just for the large images. When I try and add in medium images it doesn't work. My social links are fixed about 600px from the top. Thanks in advance!
var large_images = $('img[src*="#large"]'),
medium_images = $('img[src*="#medium"]'),
social = $('.social-share'),
$window = $(window),
showSocial = function() {
if (isHidden) {
isHidden = false;
social.fadeIn(200);
}
},
hideSocial = function() {
if (!isHidden) {
isHidden = true;
social.fadeOut(200);
}
},
isHidden = true,
scrollTop;
if (large_images.length) {
$window.on('scroll', function() {
var flag = false;
scrollTop = $window.scrollTop() + 400;
$.each(large_images, function(i, large_image) {
var $large_image = $(large_image),
offset = $large_image.offset().top;
if (offset < scrollTop && offset + $large_image.height() > scrollTop) {
flag = true;
return false;
}
});
if (flag) {
hideSocial();
} else {
showSocial();
}
});
}
Since you're only looping through #large images, you just need to also loop through #medium images. The logic you're using for #large should work fine with #medium images, assuming the only difference is the size.
You can replace your large_images, medium_images vars with all_images = $('img[src*="#large"],img[src*="#medium"]') and then change the other 2 references to large_images in your jquery to to all_images

Black space between swaping images

I'm having a issue with the website I'm creating. The truck image at the top is changing on scroll down, but while scrolling and changing the images there appears black space.
1) Images are 1400x600 JPG's, around 70kb each. I didn't lower the resolution because if someone accesses it from a 1920x1080 screen, the truck will be blurry and distorted.
2) The website is still not done, so it's on a free hosting now (000webhost.com), may this cause the images to load slower and the black space to appear?
Here is the website: http://denea.comeze.com/
Here's the script that changes the images, just in case:
var numberofscroll = 0;
var lastScrollTop = 0;
$(document).ready(function () {
var numberofscroll = 1;
var lastScrollTop = 0;
var totalImages = 4;
var dontHandle = false;
$("#home").scroll(function () {
if (dontHandle) return; // Debounce this function.
dontHandle = true;
var scrollTop = $(this).scrollTop();
(scrollTop > lastScrollTop) ? numberofscroll++ : numberofscroll--;
if (numberofscroll > totalImages) numberofscroll = totalImages;
else if (numberofscroll < 1) numberofscroll = 1;
change_background(numberofscroll);
lastScrollTop = scrollTop;
window.setTimeout(function() {
dontHandle = false;
}, 150); // Debounce!--let this handler run once every 400 milliseconds.
});
function change_background(num) {
$("#home").css("backgroundImage", "url('images/movie_" + num + ".jpg')");
};
});
Your Problem has to do with loading time.
Instead of loading the image, when the scroll begins, you can have the images you need already loaded in your page, that way you do not have any loading times, when swapping.
In HTML you have something like this:
<div class="headimg_container>
<img id="image_1" class="headimg" style="display: none" src=".......">
<img id="image_2" class="headimg" style="display: none" src=".......">
<img id="image_3" class="headimg" style="display:block" src"......">
</div>
I used headimg_container as a container element. The class should have a definitve height, so when hiding and showing your images, the container does not collapse.
And in JS you can do something like this:
function change_background(num) {
$(".headimg").hide();
$("#image_" + num).show();
};
The result would be smooth, since you can just swap the visibility of the image-tags, without any delay.
Another solution could be to use sprites, but with a few heavy images, you might want to stick with loading them separately as I suggested above.
Hope that helps!

Javascript fade in/out effect freezes when hovering quickly over images

I'm playing around with pure JavaScript, so I created a small fade in/out object, to adjust images opacity onmouseover and onmouseout. Fading works fine when the mouseover and mouseout actions are precise:
Start moving the cursor from the white background
Hover over an image
Hover back over the white background
The problem is, as soon as I start to move the mouse "naturally" from one image to another, the fading (or rather the script itself) freezes.
I'm not sure whether it's a animation-speed problem, or there's something I'm missing in the implementation.
If someone has the time to take a look, I would appreciate a peer check, so I can crack the issue and learn new stuff.
Here's a fiddle: http://jsfiddle.net/6bd3xepe/
Thanks!
As I see it, you have one INTERVAL for you FADER, you need one for each IMG.
My jsfiddle fixes this. I added an ALT-attribute to each IMG with "dome" content, so as to circumvent the jsfiddle working on non-cat-images .. ignore that part - commented out below.
There are some fundamental things wrong with the design - keeping track of objects & references is key. Usage of "this" & "that" aren't helping in the current implementation (see comments to OP). Also, on another note, the usage of "toFixed(2)" is not really required IMHO and you can shorten "o = o + 0.1" to "o += 0.1".
JS:
var fader = {
target: document.getElementsByTagName('img'),
interval: [],
speed: 25,
default_opacity: 1,
init: function() {
this.bindEvents();
},
// Get element's opacity and increase it up to 1
fadeIn: function(element) {
var element_opacity = this.getOpacity(element),
that = this,
idx = element.getAttribute('data-idx');
console.log("fI: "+idx+" "+element_opacity);
this.default_opacity = element_opacity.toFixed(2);
this.interval[idx] = setInterval(function() {
if (element_opacity.toFixed(2) < 1) {
element_opacity = element_opacity + 0.1;
element.style.opacity = element_opacity.toFixed(2);
} else {
clearInterval(that.interval[idx]);
}
}, that.speed);
},
// Get current opacity and decrease it back to the default one
fadeOut: function(element) {
var element_opacity = this.getOpacity(element),
that = this,
idx = element.getAttribute('data-idx');
console.log("fO: "+idx+" "+element_opacity);
this.interval[idx] = setInterval(function() {
if (element_opacity.toFixed(2) > that.default_opacity) {
element_opacity = element_opacity - 0.1;
element.style.opacity = element_opacity.toFixed(2);
} else {
clearInterval(that.interval[idx]);
element.removeAttribute('style');
}
}, that.speed);
},
// Get opacity of an element using computed styles
getOpacity: function(element) {
var styles = window.getComputedStyle(element),
opacity = parseFloat(styles.getPropertyValue('opacity'));
return opacity;
},
bindEvents: function() {
var that = this, count = 0;
for (var i in this.target) {
// the whole "dome" is just a fsfiddle hack - otherwise it sees 7 images instead of 4!
//if( this.target[i].alt == "dome" ){
console.log("COUNT: "+count);
this.target[i].setAttribute('data-idx',count);
this.target[i].onmouseover = function() {
that.fadeIn(this);
}
this.target[i].onmouseout = function() {
that.fadeOut(this);
}
count++;
//}
}
}
};
fader.init();

Want to keep background fixed until a certain scrolldown point

I have two background photos, I want to show the first background photo if the page is not scrolled to 500, if the page is scrolled more than 500, then I want to show the second background, both backgrounds must be positioned fixed and stretched to the screen.
Only texts must move when page scrolls, and the background must change if the scoll is more than 500.
http://jsfiddle.net/2Pfsy/37/
$(document).ready(function () {
var imageControl = function (event) {
var fromTop = $(window).scrollTop();
url = null;
console.log(fromTop);
if (fromTop < 500) {
url = 'http://i.hizliresim.com/KdrGVV.png';
} else if (fromTop > 500) {
url = 'http://4.bp.blogspot.com/-mHaVHhUegKs/UjHp6DruPeI/AAAAAAAAGx8/m_je_crr1v0/s1600/wp+cortana+screenshot+mashup.jpg';
}
$('body').css('background', 'url(' + url + ')');
};
$(window).scroll(imageControl);
});
http://jsfiddle.net/2Pfsy/43/
updated your jsfiddle
changed background to background-image in js and added background-attachment: fixed in css

Categories