The problem is my background images are of different sizes and unpredictable, so using a CSS transition will animate the stretch, which looks ugly. Thus, I really need to do this with JS.
var images = [
"http://ns223506.ovh.net/rozne/e800637ee8c7de5cdaed8df8ea3635f1/wallpaper-2585508.jpg",
"http://ns223506.ovh.net/rozne/15382371cb0d5b9319f5f4469bbc4511/wallpaper-2585497.jpg"
];
var counter = 0;
setInterval(function () {
$(".bg").css('backgroundImage', 'url("' + images[counter] + '")');
$('<img>').attr('src', images[++counter]); // preload the next image
if (counter == images.length) counter = 0;
}, 2000);
http://jsfiddle.net/mVAvF/1/
What I want to do is fade in the new background-image whilst fading out the old. Any suggestions?
You cannot fade one background into another in the same element.
You'll have to add another element on top of or behind the current background, then either fade the new element in if it is on top or fade the old one out if the new one is behind.
I answered a similar question before that contains a jsFiddle:
jQuery background image rotation script - looking to modify
Related
I am working on a simple slideshow where each slide has its own duration.
I would like to add transitions between the slides using animate.css by adding and removing classes on the current and the next slides.
My problem is that - with my current approach - only the next slide will be animated (it slides in) but the current one is just disappear without any animation.
I have tried to detect the end of the current animation and then change(adding/removing) the classes but in that case there was a huge gap between the slides...
How can make sure that two animations plays at once?`
var slides = $this.find('.slide');
slideIt = function(time) {
setTimeout(function() {
var duration = slides.eq(nextSlide).data('duration');
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut)
.hide();
slides.eq(nextSlide)
.removeClass(animateOut)
.addClass(animateIn)
.show();
slideIt(duration);
currentSlide = nextSlide; nextSlide ++;
if (nextSlide == slidesLength) { nextSlide = 0;}
},time);
};
Thank you for the help in advance!
Ps.: While typing this post I have realized that it must be the .hide() but without it only the first slide displayed.
Native CSS animations on two different elements should always run at the same time.
But if you hide an element, it disappears before the animation has even started. You have to add a timer for that.
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut);
// save the jQuery instance of the element that should be hidden.
var $currentSlide = slides.eq(currentSlide);
// hide this element later
setTimeout(function() {
$currentSlide.hide();
}, 1000); // 1000 for 1000ms, replace that with the duration of the animateOut animation
If my first answer doesn't satisfy you, because you want so solve that on the CSS side, when there is a second way:
Remove the .hide() in JavaScript.
Make sure your CSS animation ends with a state, there the element cannot be seen anymore (like transform: scale(0) or left: -100%).
Maintain that final state of the CSS animation. To do that, see: Maintaining the final state at end of a CSS3 animation
I am stuck in one problem and tried a lot but couldn't get the solution.
What happens is, there is an mp3 player and below that player there is a strip what holds pictures (comments from users) based on the mp3 progress.
When ever the progress bar of the player reach the start of the image it ads "active" class to the image so people can see that at this time this user commented.
Now the problem I am facing is that at 01:46 there are two images that overlap each other and due to this overlap the javascript is adding active class to both images which I don't want, I want if the progress bar reach the start of the first image it will make it active but as soon as the second image starts (which is overlapped) the second image gets active so that there would be only 1 active at a time. same as soundcloud comments.
No matter if the first image duration will be less but this is what i wanted to achieve, as these images will be dynamic and user can choose where ever they want to comment i can not give the specific class to overlapped images so something needs to be done through javascript which i am stuck badly.
Because now there are two overlapped but in future it can be three four or how many overlapped so i want a effect that when we move the mouse from left to right on these images how the hover effect makes pictures active and as the second picture gets in focus that become active, i want it to be that way.
Can any expert help me with this?
I am using this function to get the left position of the progress bar meets the image to add "active" class and when the width of the image end it will remove the active class
$(document).ready(function() {
function highlightImg(progress){
progress = parseFloat(parseFloat(''+progress).toFixed(1));
var imgs = $('img.comment');
imgs.map(function (i, im)
{
var img = $(im);
var currentImgLeftPos = parseFloat(parseFloat(im.style.left).toFixed(1));
var currentImgRightPos = $(this).width() / $(this).parent().width() * 100;
console.log(progress);
console.log('left' ,currentImgLeftPos);
img.removeClass('active'); // remove active from other images
if (progress > currentImgLeftPos - 1 && progress < currentImgLeftPos + currentImgRightPos ) {
$('#imgwidimg').text('this'+currentImgRightPos);
img.addClass('active'); // add the class when needed
}
}
);
}
And with this function i am making the jplayer progress update
$('#jquery_jplayer_2').on($.jPlayer.event.timeupdate, function(e){
var progress = document.querySelector('.jp-play-bar').style.width;
highlightImg(progress);
});
Here's a fiddle demonstrating the problem.
Please try with this.
if (progress > currentImgLeftPos - 1 && progress < currentImgLeftPos + currentImgRightPos ) {
$('#imgwidimg').text('this'+currentImgRightPos);
imgs.removeClass("active"); //add this line to your code
img.addClass('active'); // add the class when needed
}
I have a div that contains text next to a b&w image. The entire div is set to 50% opacity. Upon hover over this div, I want to change the opacity to 100%, while also changing the source of the image (from the b&w one to the color). The functionality is fine; however, when it's hovered over, the opacity changes slightly before the image source changes, and it definitely looks a little funky. I've tried preloading the images, but that doesn't seem to change anything - still a slight delay in changing the img source.
Here is what my code looks like (the images have the almost same source, just the suffix is different, thus the strange looking code):
$('.character').on('mouseenter', function() {
var full_src = $(this).find('img').attr('src');
var half_src = full_src.split("-");
$(this).find('img').attr('src', half_src[0] + '-color.png');
$(this).css('opacity', 1);
});
$('.character').on('mouseleave', function() {
var full_src = $(this).find('img').attr('src');
var half_src = full_src.split("-");
$(this).find('img').attr('src', half_src[0] + '-bw.png');
$(this).css('opacity', .5);
});
Any ideas? Thanks in advance.
EDIT: Threw together a fiddle: http://jsfiddle.net/3WZ7J/ - does seem to work correctly most of the time, my images might be too large or not preloading correctly.
You can wait for the image to load before changing the opacity of the div
$('.character').on('mouseenter', function() {
var $this = $(this);
var full_src = $this.find('img').attr('src');
var half_src = full_src.split("-");
$this.find('img').load(function(){
$this.css('opacity', 1);
}).attr('src', half_src[0] + '-color.png');
});
FIDDLE
One thing you could try is .promise() to force the order in which the operations take place, so that the opacity won't change until the image has swapped out. Some info here: http://api.jquery.com/promise/
I am building a website as part of some university coursework and my landing page design is fairly ambitious, designed to wow my professor.
It requires many images of different types, jpegs, pngs and animated gifs which all appear to have a negative impact on loading time and gracefulness.
So what I'm building is a little stage-themed image carousel, what I'm trying to make it do is:
Roll curtain up revealing first image
Roll curtain down & change to second image
Roll curtain up revealing second image
Roll curtain down & change to third image
Roll curtain up revealing third image
and so on.. looping through the images indefinitely
Whilst this is going on there is a simple animated spotlight gif overlaying the image carousel, running constantly.
I am aware that there are a number of ways to achieve this, I'm trying to find the most smooth and precise method. What I have managed to constuct so far is a basic image carousel that isn't very wow, and a curtain that rolls up first time only on most browsers (it only rolls up and down constantly on Dreamweaver CS5).
I am asking here because I have tried a number of different ways and have been searching the web for 3 days trying to find a relevant example to work from. Any suggestions would be greatly appreciated.
You can view a working example here
Here is my javascript:
$(document).ready(function() {
var imgs = ['images/logopic.png','images/lobby.png','images/worksofshake.jpg','images/worksofshake.jpg'];
var cnt = imgs.length;
setInterval(Slider, 6000);
function Slider() {
$('#imageSlide').fadeOut("fast", function() {
$(this).attr('src', imgs[(imgs.length++) % cnt]).fadeIn("slow");
});
$("#curtaindown").animate({height:"95%"});
/*$("#curtaindown").animate({height:"75%"});
$("#curtaindown").animate({height:"50%"});
$("#curtaindown").animate({height:"30%"});*/
$("#curtaindown").animate({height:"5%"},5000);
$("#curtaindown").animate({height:"95%"},5000);
$(".leadinfo").hide();
}
});
Thank-you for any and all help.
This solution assumes that on page load, the curtain is covering up the image and the first image is already set on #imageSlide. I haven't tested it, but the general idea should be correct. One problem with this solution is that with a bad internet connection, there's a chance the curtain will pull away before the image is actually done downloading. Accounting for that is a bit messier, so I didn't get into it.
var imgs = [...];
var nextImage = 1;
var $image = $('#imageSlide');
var $curtain = $('#curtaindown');
hideCurtain();
preloadNextImage();
// Show the next image in 6 seconds
setTimeout(showNextImage, 6000);
function showNextImage() {
showCurtain(function(){
// Set the img tag to the new image
$image.attr('src', imgs[nextImage]);
nextImage++;
if (nextImage.length >= imgs.length)
nextImage = 0;
preloadNextImage();
// After the curtain is hidden, wait 5 more seconds before
// switching to the next one.
hideCurtain(function(){
setTimeout(showNextImage, 5000);
});
});
}
function showCurtain(onComplete) {
$curtain.animate({height:'95%'},
{ duration: 500,
complete: onComplete });
}
function hideCurtain(onComplete) {
$curtain.animate({height:'5%'},
{ duration: 500,
complete: onComplete });
}
function preloadNextImage() {
// Start downloading the next image.
(new Image()).src = imgs[nextImage];
}
I eventually settled on a very simple implementation that works even though I'm fairly sure it logically shouldn't. If someone could comment to explain why it does work I'd be very grateful.
This is the code I eventually used:
<script type="text/javascript">
$(document).ready(function() {
$("#scroller_container_top").hide();
var imgs = ['images/logopic.png','images/lobbywithcaption.jpg','images/seatswithcaption.jpg','images/worksofshake.jpg'];
var cnt = imgs.length;
setInterval(Slider, 10000);
function Slider() {
$('#imageSlide').fadeOut("slow", function() {
$(this).attr('src', imgs[(imgs.length++) % cnt]).fadeIn("slow");
});
$("#curtaindown").animate({height:"5%"},5000);
$("#curtaindown").animate({height:"95%"},5000);
};
</script>
So far I have got jCarousel to display, and load the images via a txt file,
What I want to do is show 4 images at a time, then when the user puts the mouse over 1 of the images the other 3 images to fade opacity, to 30%. Then if they move the mouse to the image next to it I want that image to be 100% opacity and the other 3 images 30% opacity.
So the image with the mouse over it will always be 100% opacity, and the others 30%, so it stands out. When the user moves the mouse out of the jCarousel box I want all images to show 100% opacity.
I'm using code similar to this
Thanks.
Edit
Sorry I should have added code before, here it is: http://pastebin.com/m54cd73d8
This is what I have so far nickrance.co.uk/jcarousel/dynamic_ajax.html
It kind of works, it fades the inactive images, but I think it needs a mouseout event to restore the opacity of all images when the mouse moves out of the jCarousel div.
Also, it seems to be only working for the first 4 images, and I have 10 images in the carousel, the others don't seem to do anything :s
New Current code:
So far
$(window).bind("load", function() {
var activeOpacity = 1.0,
inactiveOpacity = 0.3,
testOpacity = 0.3,
fadeTime = 50,
clickedClass = "selected",
thumbs = "#mycarousel li";
$(thumbs).fadeTo(1.0, activeOpacity);
$(thumbs).hover(
function(){
$(thumbs).fadeTo(fadeTime, inactiveOpacity);
$(this).fadeTo(fadeTime, activeOpacity);
},
function(){
// Only fade out if the user hasn't clicked the thumb
if(!$(this).hasClass(clickedClass)) {
$(this).fadeTo(fadeTime, activeOpacity);
}
});
$(thumbs).click(function() {
// Remove selected class from any elements other than this
var previous = $(thumbs + '.' + clickedClass).eq();
var clicked = $(this);
if(clicked !== previous) {
previous.removeClass(clickedClass);
}
clicked.addClass(clickedClass).fadeTo(fadeTime, activeOpacity);
});
});
You can add this code to yours and you will be fine:
$(".jcarousel-wrapper").on('mouseleave', function(){
$(thumbs).fadeTo(fadeTime, 1.0);
});
And your HTML must be something like this:
<div class="jcarousel-wrapper">
<div class="jcarousel">
<ul id="mycarousel">
<li>...
Then all images will fade opacity to 1 when mouse leave your carousel...