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!
Related
I have a chart made using d3.js:
Code for chart
I have put this chart within a website.
website
Problem is that in the above website, when you scroll through the page to the "teamchart" section, I don't see the effect of the chart. When you refresh the page, you can see the chart role the effect.
I want the chart to role and show the effect, when I reach that section of the page or when I use the nav bar, click "teamchart" and reach that section.
I used the below JavaScript code, but it's repeating it continuously:
$(document).scroll(function() {
//Basically your position in the page
var x = $(this).scrollTop();
//How far down (in pixels) you want the user to be when the effect to starts, eg. 500
var y = 500;
if (x > y) {
//Put your effect functions in here.
}
});
Fiddle related to the website:
My code related to website (experiment here)
As i understand, your problem is the part where the animation keeps playing.
this is because every time you scroll the page, to a value greater then 500, you actually repeating your code.
Easy solution: place a flag to signal 'alreadyAnimated'
var g_pieChartAnimated=false;
$(document).scroll(function() {
//Basically your position in the page
var x = $(this).scrollTop();
//How far down (in pixels) you want the user to be when the effect to starts, eg. 500
var y = 500;
if (!g_pieChartAnimated && (x > y)) {
g_pieChartAnimated = true;
//Put your effect functions in here.
}
});
Second solution (bit faster):
is to detach the event handler once it did what you want.
function onScroll_AnimateChart() {
//Basically your position in the page
var x = $(this).scrollTop();
//How far down (in pixels) you want the user to be when the effect to starts, eg. 500
var y = 500;
if (!g_pieChartAnimated && (x > y)) {
$(document).off('scroll', onScroll_AnimateChart); // remove myself from the event handlers, so it won't be called again.
//Put your effect functions in here.
}
}
$(document).on('scroll', onScroll_AnimateChart);
Edit
I missed where you said the animation was repeating - #Tomer W solution is correct.
Similar to what #Tomer W posted, but run the chart function (or the chart the whatever function triggers the animation) in your scroll handler:
var chartInit = false;
var handler = function() {
var y = 500;
var x = $(this).scrollTop();
if (x > y && !charInit) {
charInit = true;
someD3ChartStuff();
}
};
$(document).scroll(handler);
I have the 2 following solutions for your issue, hope it helps!
1 - Pure css + jQuery solution
$(window).on('scroll' , function(){
scroll_pos = $(window).scrollTop() + $(window).height();
element_pos = $(".chart-wrapper").offset().top + $(".chart-wrapper").height() ;
if (scroll_pos > element_pos) {
$(".chart-wrapper").addClass('animation');
};
})
and after that manipulate your animation in the class animation
2- Wow.JS Library
1- Download the script here
2- Download the animate.css here
3- Use this snippet as example and understand how it works
<script src="http://mynameismatthieu.com/WOW/dist/wow.min.js"></script>
<link rel="stylesheet" href="css/animate.css">
<script>
new WOW().init();
</script>
<div class="wow bounceInLeft animated">
<h2>animated heading</h2>
</div>
Obs.: There's a bunch of animations that you can use with this library + animate.css just use any of the classes below and put the class wow also
Here's the list
bounce
flash
pulse
rubberBand
shake
headShake
swing
tada
wobble
jello
bounceIn
bounceInDown
bounceInLeft
bounceInRight
bounceInUp
bounceOut
bounceOutDown
bounceOutLeft
bounceOutRight
bounceOutUp
fadeIn
fadeInDown
fadeInDownBig
fadeInLeft
fadeInLeftBig
fadeInRight
fadeInRightBig
fadeInUp
fadeInUpBig
fadeOut
fadeOutDown
fadeOutDownBig
fadeOutLeft
fadeOutLeftBig
fadeOutRight
fadeOutRightBig
fadeOutUp
fadeOutUpBig
flipInX
flipInY
flipOutX
flipOutY
lightSpeedIn
lightSpeedOut
rotateIn
rotateInDownLeft
rotateInDownRight
rotateInUpLeft
rotateInUpRight
rotateOut
rotateOutDownLeft
rotateOutDownRight
rotateOutUpLeft
rotateOutUpRight
hinge
rollIn
rollOut
zoomIn
zoomInDown
zoomInLeft
zoomInRight
zoomInUp
zoomOut
zoomOutDown
zoomOutLeft
zoomOutRight
zoomOutUp
slideInDown
slideInLeft
slideInRight
slideInUp
slideOutDown
slideOutLeft
slideOutRight
slideOutUp
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 () {
/* ... */
}
}
I'm making a simple image slider for the landing page of a website. There are two effects taking place. First, the image transitions by fading the current one in and the subsequent one out, using setInterval. There are also arrow buttons that, when clicked, slide the images forward or backward. The fading is working just fine, but the sliding functions are leaving the images in the offscreen position. Here are:
function slidePrevPic(dur){
var currentPic = $('.active-pic');
var prevPic = currentPic.prev();
if(prevPic.length == 0){
prevPic = $('#pics img').last();
}
$('.arrow').css('pointer-events','none');
setTimeout(function(){
$('.arrow').css('pointer-events','auto');
},dur);
w = $(window).width();
prevPic.css('opacity',.4);
prevPic.css('left',-w);
prevPic.animate({
'left': 0
}, dur);
currentPic.animate({
'left': w
}, dur);
setTimeout(function(){
currentPic.css('left',0);
currentPic.css('opacity',0);
},dur);
prevPic.addClass('active-pic');
currentPic.removeClass('active-pic');
};
function slideNextPic(dur){
var currentPic = $('.active-pic');
var nextPic = currentPic.next();
if(nextPic.length == 0){
nextPic = $('#pics img').first();
}
$('.arrow').css('pointer-events','none');
setTimeout(function(){
$('.arrow').css('pointer-events','auto');
},dur);
w = $(window).width();
nextPic.css('opacity',.4);
nextPic.css('left',w);
nextPic.animate({
'left':0
},dur);
currentPic.animate({
'left':-w
},dur);
setTimeout(function(){
currentPic.css('left',0);
currentPic.css('opacity',0);
},dur);
nextPic.addClass('active-pic');
currentPic.removeClass('active-pic');
};
I was trying to simplify everything to figure out what was wrong, so instead of hiding and showing images or fading them in and out, I'm just animating and setting the opacity. The idea here is pretty simple. All of the pictures are in the same place and all but one have 0 opacity. When the slider is called, the next image is moved offscreen, the current and next image are animated together (moving the current image offscreen), then the position of the current image should be reset. The sliding effect is working well, but the position of the current image is not reset, so that when it cycles back the image space goes white. I am still generally confused about how the timing of function execution with jquery and js is managed, so any help in that general direction is also much appreciated. Also, here is the code that calls these functions:
var picInterval = setInterval(function(){
fadeNextPic(picFadeTime);
},idleTime);
$('#banner #right-arrow').click(function(){
clearInterval(picInterval);
slideNextPic(picSlideTime);
picInterval = setInterval(function(){
fadeNextPic(picFadeTime);
},idleTime);
});
$('#banner #left-arrow').click(function(){
clearInterval(picInterval);
slidePrevPic(picSlideTime);
picInterval = setInterval(function(){
fadeNextPic(picFadeTime);
},idleTime);
});
I would like to have a logo image change (for the purpose of color) upon scrolling.
The navigation currently changes when scrolling downwards to have a dark bar behind it, does anybody have any suggestions as to what will work best for this image replacement?
I have tried using this as found in another SO question but wouldn't work for me....
$(function(){
$(window).scroll(function(){
if($(this).scrollTop() > 100) {
$('logo_h logo_h__img').fadeOut('slow');
$('#logo-img img')
.css({'width':'184px','height':'33px'})
.attr('src','logo1.png');
}
if($(this).scrollTop() < 100) {
$('logo_h logo_h__img').fadeIn('fast');
$('#logo-img img')
.css({'width':'184px','height':'60px'})
.attr('src','logo2.png');
}
});
});
Filenames replaced for the sake of demonstration.
Thank you!
Thanks to help from #rlemon I have a script that works better, now implementing it is the task I am having trouble with!!
<!-- Logo Scroll -->
var img = document.querySelector('.logo_h__img img'); // get the element
img.dataset.orig = img.src; // using dataset is just being fancy. probably don't do this
document.addEventListener('scroll', function (e) { // add the event listener
if (document.body.scrollTop > 0) { // check the scroll position
img.src = img.dataset.scroll; // set the scroll image
} else {
img.src = img.dataset.orig; // set the original image back
}
});
I'm having trouble with a concept with a HTML5/jQuery slideshow system...
I want the images to constantly rotate, without stopping. The way I have it set up now is just going to the first image by changing the margin-left back to 0 when I run out of slides. I'd much rather have it continue indefinitely.
While I'm at it...Is there a way to read a property from the stylesheet? It'd be better if I could ask a user to point the script to the stylesheet and pull the sizing and stuff from there.
Demo: http://bearce.me/so/slideshow
Script (mainly focus on the CSS version, I can convert it to the jQuery version once I understand how to do it):
// JavaScript Document
var slides = 4; // number of slides
var time = 3; // time per slide (in seconds)
var width = 600; // width of slideshow (ex: 600)
var transition = .5 // transition time (in seconds) (for older browsers only, edit css for newer)
window.onload = function start() {
if(Modernizr.csstransitions) {
cssslide();
} else {
jqueryslide();
}
}
function cssslide() {
document.getElementById("container").style.width=(width * slides) + "px";
var num = 0;
setInterval(function() {
num = (num + 1) % slides;
document.getElementById('container').style.marginLeft = (("-" + width) * num) + "px";
}, time * 1000);
}
function jqueryslide() {
$("#container").width((width * slides) + 'px');
var num = 0;
setInterval(function() {
num = (num + 1) % slides;
$("#container").animate({marginLeft: (("-" + width) * num) + "px"},{duration: (transition * 1000)});
}, time * 1000);
}
EDIT: To clarify, I don't want it to constantly scroll, I want it to scroll, stop for a few seconds, scroll, stop, scroll, stop like it does, but instead of zooming all the way back to the first image, I just want it to keep going.
When your slideshow initializes, use JS to duplicate your first image so that the markup looks like this:
<div id="container">
<img src="setup/slides/portal2.jpg" />
<img src="setup/slides/crysis2.jpg" />
<img src="setup/slides/deadspace2.jpg" />
<img src="setup/slides/acb.jpg" />
<img src="setup/slides/portal2.jpg" />
</div>
Then once the 5th slide (duplicate of slide 1) is visible, clear your interval, reset your margin to 0 and re-initialize your slideshow.
I would seriously rethink your approach. Just tacking on more DOM elements into infinity is seriously inefficient, and would probably be an accessibility nightmare.
I would suggest you check out the jQuery Cycle plugin - it's real easy to implement, and allows you to loop infinitely.