I have a series of images which change their image when hovering on them and also a div animate (as an overlay) on the image during hover.
The code is as follow:
// hide overlays
$(".mini-shop .item .image a div").hide();
// toggle overlay and second image
$(".mini-shop .item .image").hover(
function() {
$img = $(this).find('a img');
$img.stop().hide();
var src = $img.attr('src');
$img.attr('src', $img.attr('data-csrc'));
$img.stop().fadeIn(300);
$img.attr('data-csrc', src);
$(this).find('a div').stop().animate({
'top': '80%'
}, 300).css('display', 'block');
},
function() {
$img = $(this).find('a img');
$img.stop().fadeOut(100);
var src = $img.attr('src');
$img.attr('src', $img.attr('data-csrc'));
$img.stop().fadeIn(300);
$img.attr('data-csrc', src);
$(this).find('a div').stop().animate({
'top': '100%'
}, 300).css('display', 'none');
}
);
my problem is, only the effects in the first function (mouseenter) work and in the mouseleave method the overlay disappears immediately and the fade effect does not work! What is the problem of this code?
I know this may be a bit of a hassle, but have you tried separating them into one mouseenter() function and the other a mouseleave()? I know the hover() is supposed to cover both, however, I see no errors in your code so I cannot propose much more than to do what I have said.
Related
I don't know how much people have used this plugin, demo but what I want is to change the default behavior of the plugin to something like animated. Currently, when you click on next or previous button, the images will be just appended without any visual animation. I just want to animate the images while appending! Can anybody suggest any good solution!! Below is the code where appending on the image takes place:
if (href.match(/\.(jpeg|jpg|gif|png)$/i) !== null) {
var img = $('<img>', { src: href });
img.one('load', function () {
var wrap = $('<div class="nivo-lightbox-image" />');
wrap.append(img); //gets appended here
content.html(wrap).removeClass('nivo-lightbox-loading');
// Vertically center images
wrap.css({
'line-height': $('.nivo-lightbox-content').height() + 'px',
'height': $('.nivo-lightbox-content').height() + 'px' // For Firefox
});
}).each(function () {
if (this.complete) $(this).load();
});
}
OK with any sort of animation
Well I just added a fadeIn after appending which seems to do some sort of animation although which is what I was accepting. Here is what I did:
wrap.append(img).fadeIn('4000');
Does anyone knows how to transform this jQuery effect, instead of having fixed sized images, I need to set the size in percentage (width:100%; height:auto) so they can be responsive. Any ideas?
<script type="text/javascript">
$(function (){
$('img.fade').each(function (){
var $$ = $(this);
var target = $$.css('background-image').replace(/^url|[\(\)'"]/g, '');
$$.wrap('<span style="position: relative;"></span>')
.parent() // span elements
.prepend('<img>')
.find('img:first')
.attr('src', target);
$$.css({
'position' : 'absolute',
'left' : 0,
'top' : this.offsetTop
});
$$.hover(function () {
$$.stop().animate({
opacity: 0.2
}, 250);
}, function () {
$$.stop().animate({
opacity: 1
}, 350);
});
});
});
</script>
I think you mean that the background image isn't scaling.
You could use the css command "background-size" to solve this problem..
Values that could help you are "cover" or "contain":
http://www.w3schools.com/cssref/css3_pr_background-size.asp
var target = $$.css('background-image').replace(/^url|[\(\)'"]/g, '').css({ 'background-size': 'cover' });
If this is not working, you could read out the actual absolute width of your image an set it as background-size. But then you need an resize-event for when you're scaling the browser window..
I would recommend to use two pictures and show/hide the pictures instead of using a background-image for the hover.
I am making a gallery with thumbnails. It works but I want to make an image transition, and I want it to fades in. In this case it fades in but only for the first image. The next images show up without any animation.
$('.picture').click(function() {
$("#screen img").attr('src', $(this).attr('src')).animate({
height: "400px"
}, 2000);
});
And also, can someone tell me how to position the image in the div to be centrally placed using the width and the height of the div and the image? I don't want to use plugin for the gallery, so I would appreciate your help very much.
To maintain your current transition try
var $simg = $("#screen img");
$('.picture').click(function () {
var $img = $(this);
if ($simg.height() == 0) {
$("#screen img").attr('src', $(this).attr('src')).animate({
height: "400px"
}, 2000);
} else {
$("#screen img").animate({
height: "0"
}, function () {
$(this).attr('src', $img.attr('src')).animate({
height: "400px"
}, 2000)
});
}
});
Demo: Fiddle, using fade animation
I have a stack of images I'm bringing in from YouTube, and I want the top image to fade out on hover and then start a rotating slideshow of the next 3 images. I've almost got it working but I'm having an issue with getting the SetInterval to stop when I hover off of the thumbnail.
thumbRotate: function(){} //This is up in the main object
//hover state over thumbs and slideshow animation
$('#youtube-widget ul a').hover(
// hover-in
function(){
$this = $(this);
$(this).children('.title-overlay').children('h5, img, span').stop(true, true).animate({opacity: '0'}, 200, function() {
$.Modules.VideoWidget.thumbRotate = setInterval(function() {
var topImage = $this.children('img:first');
topImage.stop(true, true).fadeOut(500).next().stop(true, true).fadeIn(500).end().appendTo($this);
}, 2000);
});
//hover-out
}, function() {
clearInterval($.Modules.VideoWidget.thumbRotate);
$(this).children('.title-overlay').children('h5, img, span').stop(true, true).animate({opacity: '1'}, 200);
}
);
edit: I noticed that hovering over the thumbnail seems to be increasing animation exponentially. For some reason the animations seem to be stacking up on themselves, but I don't really understand why.
Here is the problem - .hover() and .mouseover()...
Both of these functions perform an action not only when the cursor enters the element but also every time the mouse moves a single pixel within the element. In other words those 2 functions are great for simpler interactions, but it is necessary to use .mouseenter() and mouseleave() to setup interval functions otherwise you end up setting a new interval every time the cursor moves within the element (which can be a lot).
new fiddle - http://jsfiddle.net/b3Mb8/2/
new code -
//thumb rotate animation on hover
function startRotate($this) {
$.Modules.VideoWidget.thumbRotate = setInterval ( function() {
topImage = $this.children('img').filter(":first");
topImage.animate({opacity: '0'}, 500).next().animate({opacity: '1'}, 500).end().appendTo($this);
}, 800);
}
function stopRotate() {
clearInterval($.Modules.VideoWidget.thumbRotate);
}
$("#youtube-widget ul a").mouseenter(function() {
$this = $(this);
startRotate($this);
}).mouseleave(function() {
stopRotate();
});
//hover state over thumbs and slideshow animation
$('#youtube-widget ul a').hover( function(){
$this.children('.title-overlay').children('h5, img, span').stop(true, true).animate({opacity: '0'}, 300, function() {
});
//hover-out
}, function() {
$this.children('.title-overlay').children('h5, img, span').stop(true, true).animate({opacity: '1'}, 300);
});
It's an issue with your variable name I think. It's working here:
I just added this and used it in both intervals
var hoverInterval;
http://jsfiddle.net/b3Mb8/
I currently use the following to fade images on my site:
$(document).ready(function() {
$('ul.image-switch li').mouseover(function(e) {
if (e.target.nodeName.toLowerCase() == 'a') return;
var image_src = $('a', this).data('image');
var img = $('.image-container img');
if (img.attr('src') != image_src) { // only do the fade if other image is selected
img.fadeOut(200, function() { // fadeout current image
img.attr('src', image_src).fadeIn(200); // load and fadein new image
});
}
});
});
An example of this in action is at http://www.sehkelly.com/#news.
As you can see, the current image must fade out before the new one fades in.
I'd like the action to be simulaneous. Please -- does anyone know how I can achieve this?
Many thanks.
EDIT: Clueless novice. Code examples very much appreciated.
Create a new img element on top of the actual one, then fadeIn this new image. You'll need a bit of css to put the new image on top of the old one.
In no way you can do that with only one img element.
if (img.attr('src') != image_src) { // only do the fade if other image is selected
img.after(
$('<img />').attr('src', image_src).fadeIn(200)
);
img.fadeOut(200);
}
You would too want to wait for the new image to be loaded before starting fades. (checkout jQuery doc for the right function for that, and fade the images in the load callback).
Here's an implementation of Ulflander's idea, since the code posted is not complete http://jsfiddle.net/8nBqD/1/
The trick is to absolutely position the second image on top of the one you're fading out
HTML
<img id='pic1' src="http://periodictable.com/Samples/009.3b/s7.JPG" />
<img id='pic2' src="http://icons.iconarchive.com/icons/vargas21/aquave-metal/256/Sample-icon.png" />
CSS
#pic2 {
position: absolute;
display: none;
}
JS
// Fade out the image, and replace it with the new one after the fade is over
$("#pic1").fadeOut(500, function() { // fadeout current image
this.src = 'http://icons.iconarchive.com/icons/vargas21/aquave-metal/256/Sample-icon.png';
$(this).show();
});
// Fade in the new image placing it on top of the original one
$("#pic2").offset($("#pic1").offset()).fadeIn(500, function(){
// Hide it since we are showing the original image with the new src
$(this).hide();
});
We could even write a plugin to make this easy to reuse
(function($) {
$.fn.imageFader = function(newSrc, seconds) {
$(this).each(function() {
var $img = $(this);
$img.fadeOut(seconds, function() {
this.src = newSrc;
$img.show();
});
var $tempImg = $('<img src="'+newSrc+'" style="position:absolute;display:none;" />').appendTo('body');
$tempImg.offset($img.offset()).fadeIn(seconds, function(){
$tempImg.remove();
});
});
};
})(jQuery);
And use it like http://jsfiddle.net/8nBqD/5/
$('img').imageFader('picture.png', 1000);