cross-fade images in jQuery - javascript

I have an image on a web page, and have it change when the jQuery slider is moved:
HTML:
<img src="images/flask_image1.png" alt="Isa lab" id="flask" />
Slider HTML:
<div id="slider1">
Script:
<script>
$(function() {
$( "#slider1" ).slider({
min: 0,
max: 4,
step: 1,
change: function(event, ui){
if(ui.value == 1){
$('#flask').fadeOut(100);
$('#flask').attr('src','images/flask_image2.png');
$('#flask').fadeIn(100);
}else{
$('#flask').attr('src','images/flask_image1.png');
};
}
});
});
</script>
However what this does is the image fades out, changes, then fades in which "works" but it momentarily fades to nothing.
Is there a way to cross-fade the 2 images?

here you go, quiet simple I suppose, much less code and difficulty comparing with implementing some plugins: http://jsfiddle.net/gcvqr/2/
HTML
<img src="http://macnetized.com/wp-content/uploads/2014/02/Apple_Logo_csh_by_wiimon.png" id="slider">
<button>Change Image</button>
jQuery
var stopWorking=false;
var firstSrc="http://macnetized.com/wp-content/uploads/2014/02/Apple_Logo_csh_by_wiimon.png";
var secondSrc="http://technicallyeasy.net/wp-content/uploads/2011/04/apple-logo.jpg";
$('button').click(function(){
if(!stopWorking){
stopWorking=true;
$('body').append('<img src="'+$('#slider').attr('src')+'" id="fadingImg">');
$('#fadingImg').css({
'position':'absolute',
'width':'400px',
'height':'400px',
'top':'0px',
'left':'0px'
});
if($('#slider').attr('src')==firstSrc){
$('#slider').attr('src',secondSrc);
}
else{
$('#slider').attr('src',firstSrc);
}
$('#fadingImg').fadeOut(1000,function(){
$('#fadingImg').remove();
stopWorking=false;
});
}
});
NOTE:
in order to make it work in your page, you need to give #fadingImg the style of your slider img, to be positioned right over it.

Related

Script not firing properly after preloader script

Very limited script experience.
I am attempting to get a preloader to cover my images loading in a bootstrap carousel before a second script cycles through them.
This script is as far as I can get.
<!-- Preloader -->
<script type="text/javascript">
//<![CDATA[
$(window).load(function() { // makes sure the whole site is loaded
$('#status').fadeOut(); // will first fade out the loading animation
$('#preloader').delay(50).fadeOut('slow'); // will fade out the white DIV that covers the website.
$('body').delay(50).css({'overflow':'visible'});
})
//]]>
</script>
and
<!-- Script to Activate the Carousel -->
<script type="text/javascript">
$('#preloader').delay(50).fadeOut('slow', function(){
$('.carousel').carousel({
pause: "none",
interval: 500
});
});
</script>
The sequence I need is loading animation div covering images loading in "#myCarousel" > images have loaded > covering div fades out > fade out calls:
$('.carousel').carousel({
interval: 500, //changes the speed
pause: "none",
})
Images flick through and stops on final slide.
In the example above, it seems to work – the preloader works, the carousel works too but not at the expected speed; "500" is meant to be half a second. It also seems to break the pause function to, the fact pause is set to "none" seems to be ignored.
After some help from #Shikkediel the script now reads:
<script type="text/javascript">
$(window).on('load', function() {
$('#status').fadeOut()
.queue(function() {
$('#preloader').delay(50).fadeOut('slow', function() {
$('#myCarousel').attr('data-ride', 'carousel');
$('.item').first().addClass( 'active' );
$('body').delay(50).css({'overflow':'visible'});
$('.carousel').carousel({
});
});
$(this).dequeue();
});
});
</script>
– the speed and pause are now set in the data attributes, which is great to have them set in there out of the way.
However, the preloader still does not pre load the images!
This is the test I have running: http://maxsendak.com/test/pu_v2/max_page.html
This was the first draft, a bit of optimised script :
$(window).on('load', function() {
$('#status').fadeOut()
.queue(function() {
$('#preloader').delay(50).fadeOut('slow', function() {
$('#myCarousel').attr('data-ride', 'carousel');
$('.item').first().addClass('active');
$('body').delay(50).css({'overflow':'visible'});
$('.carousel').carousel({
interval: 500,
pause: 'none'
});
});
$(this).dequeue();
});
});
But it didn't quite have the expected result - the images are set as background and not detected by the onload event. I would propose preloading, appending to the document and hiding. This should cache them for the slider. Doing an Ajax call doesn't seem to fit well here :
$(document).ready(function() {
var path = 'http://www.maxsendak.com/test/pu_v2/img/people/max/';
for (var i = 1; i <= 5; i++) {
$('<img class="preload" src="' + path + i + '.jpg" alt=""/>').appendTo('body');
}
$('.preload').each(function() {
$(this).one('load', function() {
$(this).hide();
});
});
$(window).on('load', function() {
$('#status').fadeOut()
.queue(function() {
$('#preloader').delay(50).fadeOut('slow', function() {
$('#myCarousel').attr('data-ride', 'carousel');
$('.item').first().addClass('active');
$('body').delay(2500).css({'overflow':'visible'}); // after slider finishes
$('.carousel').carousel();
});
$(this).dequeue();
});
});
});
That bit of script could be left out of course if the images weren't background, the onload event should then be enough and prevent the flashing in between slides.
Minor update - according to this article Firefox can have some issues (version 37 on Windows 7 desktop at least) with the style of the preloaded images not matching that of the targeted background images. So I've added the relevant style I can see on the slider here which should be enough (also made appending the images a bit more readable) :
for (var i = 1; i <= 5; i++) {
$('<img class="preload" alt=""/>')
.attr('src', path + i + '.jpg')
.css({'height': '100%', 'position': 'relative', 'left': 0})
.appendTo('body');
}
Hope that's the final detail for a smooth cross browser functionality.

append and remove elements on upcount and downcount

I've a question on the jQuery UI Slider widget. What I intend to do is, that on every upcounting value the slider appends me an image in a div:
$("#divOne").slider({
range: "min",
min: 1,
max: 10,
slide: function (event, ui) {
console.log(ui.value);
if(ui.value == 1) {
$('#divOne').append('<img class="linkimg" src="img/link/zwei.png">');
}
if(ui.value == 2) {
$('#divOne').append('<img class="linkimg" src="img/link/drei.png">');
}
if(ui.value == 3) {
$('#divOne').append('<img class="linkimg" src="img/link/eins.png">');
}
},
change: function (event, ui) {
//alert('Stopped at ' + ui.value);
}
});
works good so far.
The problem is, I want to remove the elements if I'm then downcounting but then if I cross one number it of course appends again, so I guess compare the value in that if-statement is wrong.
Does anyone of you has a hint? Cheers
EDIT: I have made an image to show what I want to do CLICK
Assume placing all the images in html
/* cache collection of images*/
var $images= $("#divOne img")
$("#divOne").slider({
slide:function(e,ui){
if( ui.value !== $images.filter(':visible').length){
$images.hide().slice( 0, ui.value).show();
}
}
});
What this does is track number visible vs slider value.... if they don't match it hides all and shows the ones that match slider.
If you have a large number... this should be upgraded to track direction of slider and only modify affected images to improve performance
First change the image names to match the values. E.g., 1.png, 2.png. Then you can:
var i, maxVal = ui.value, html='';
for (i = 1; i <= maxVal; i += 1) {
html += '<img src="img/' + i + '.png';
}
$('#divOne').html(html);
EDIT: But in general a better approach is to have all images in the container and then construct a stylesheet that would map classes that match values to appropriate state. E.g.:
<div class="score[X]"> <!-- where `[X]` will be the actual value of the ui.value -->
<img class="val1" src="1.png">
<img class="val2" src="2.png">
<img class="val3" src="3.png">
</div>
In css:
.score1 .val2 { display: none; }
.score1 .val3 { display: none; }
....
Or some other variation of the above.
EDIT:
Example fiddle with a slightly different approach for CSS: http://jsfiddle.net/gwQAW/
EDIT2:
And version with HTML5 slider: http://jsfiddle.net/gwQAW/2/ (sorry, no time for jQuery UI right now)

Dynamic style - manipulating CSS with JavaScript

I have an image slider in a worpress theme that is currently using inline styles to change the display from block to none depending on which slide it is. Is there a way to separate this so that it will change dynamically in the js rather than using an inline style? It is changing to display block when it becomes the current slide.
html:
<div class="single_fading_slide staged_slide" style="display: none;">
<div class="positioning load_slide_image">
<span id="355_img_1">
<img src="http://imagehere" title="" alt="" width="960" height="340" class="slide_image">
</span>
</div><!-- .positioning .slide_image -->
<div class="slide_overlay"></div>
</div>
Script:I am new to js so any help is appreciated. I am sure not all of this applies but wanted to include it so you could see it.
<script type="text/javascript">
/* <![CDATA[ */
jQuery(document).ready(function(){
// Add class nopreload to all images in 'slide_content' div
if( jQuery('.slide_content').length>0 ) {
jQuery('.slide_content').find('img').addClass('nopreload');
}
jQuery('#fading_slides').preloader({
imgAppend: '.load_slide_image',
fade: false,
slider: true,
onDone: function(){
jQuery('#slider_module .mysite_preloader_large').remove();
jQuery('.slider_nav').tabs('#fading_slides > div.single_fading_slide', {
effect: 'fade',
fadeInSpeed: 'fast',
rotate: true,
onBeforeClick : function(event,index) {
if(this.getPanes().eq(index).children().eq(0).find('.vimeo_video').length>0) {
var vimeo_video = this.getPanes().eq(index).children().eq(0).find('.vimeo_video').parent().html();
this.getPanes().eq(index).children().eq(0).find('.vimeo_video').parent().empty().html(vimeo_video);
jQuery('.vimeo_video').each(function(index, vimeo_video){
Froogaloop.init([vimeo_video]);
vimeo_video.addEvent('onLoad', VimeoEmbed.vimeo_player_loaded);
});
}
if(this.getPanes().eq(index).children().eq(0).find('.youtube_video').length>0) {
var vimeo_video = this.getPanes().eq(index).children().eq(0).find('.youtube_video').parent().html();
this.getPanes().eq(index).children().eq(0).find('.youtube_video').parent().empty().html(vimeo_video);
jQuery('.youtube_video').each(function(index, youtube_video){
onYouTubePlayerAPIReady(youtube_video.id);
});
}
_class = this.getPanes().eq(index).attr('class');
jQuery('#slider_module_inner').removeClass();
jQuery('#slider_module_inner').addClass( _class.replace('single_fading_slide ', '') );
if(this.getPanes().eq(index).children().eq(0).find('.vimeo_video').length>0 && typeof navScript != 'undefined'){
setTimeout(function(){
jQuery('.slider_nav_thumb .slider_nav').animate({opacity:0},300);
jQuery('.slider_nav_thumb .slider_nav').animate({height:'0px'},300);
}, 1000 );
}
},
onClick : function(event,index) {}
}).slideshow({clickable:false, autoplay:true, interval:4000, autopause:true});
jQuery('#fading_slides').removeClass('noscript');
jQuery('.slider_nav').removeClass('noscript');
}
});
});
/* ]]> */
</script>
Thanks so much for any help!
You can use jQuery’s .show() and .hide() to handle this:
$('#selector').show();
$('#selector').hide();
I would highly recommend to spend some time reading the jQuery API documentation, I’m sure you’d be able to reduce the amount of code required a lot.

Change opacity of 2 elements to give a crossfade effect

I am working on some functionality for an e-commerce where by a user clicks a products colour, and the previous image of the products fades out while the new product fades, I am trying to achieve a cross fade effect, however I have flicker effect in there which I do not want, I think it comes when I am removing the old image from the dom, here is a fiddle to show you what I trying to do.
http://jsfiddle.net/L9Z5G/
I hope this is what you were looking for: Demo
$('.colours').click(function() {
if ($('#' + $(this).html().toLowerCase()).attr('class') == 'active') { return; }
var active = $('.active');
var next = $('#' + $(this).html().toLowerCase());
active.fadeOut(500, function() {
$(this).toggleClass('active');
});
next.fadeIn(500, function() {
$(this).toggleClass('active');
});
});​
Is it not easier to use .hide() and .show(), and just let them crossfade themselves?
To bind a click event, you use click() heres how.
$('#color1').click(function(){
$('#image1').fadeOut('fast');
});
Try this please: Working demo http://jsfiddle.net/djMZe/1/ or http://jsfiddle.net/R7u8G/1/
Hope it fits the needs! :)
code
$("#colours li").click(function() {
$(".large-image:first-child:not(.new)").animate({
opacity: 0
}, 500);
var img = $("<img />").attr('src', $(this).data("alternative")).attr("class", "large-image new");
img.css({
opacity: 0
})
$(".zoom-image").append(img);
//img.animate({ opacity : 1}, 500);
img.css({
"opacity": "1"
}).fadeIn("slow");
$(".large-image:not(:last-child)").remove();
});​
See This DEMO, hope you've required this effect.
EDITED: UPDATED FIDDLE
jQuery Cycle Plugin
$('#slideshow').before('<ul id="nav">').cycle({
fx: 'fade',
speed: 'fast',
timeout: 0,
pager: '#nav',
// callback fn that creates a thumbnail to use as pager anchor
pagerAnchorBuilder: function(idx, slide) {
return '<li><img src="' + slide.src + '" width="50" height="50" /></li>';
}
});​
SEE REFERENCE

How to display the current slider value on the jQuery slider knob?

I'm trying to figure out from the jQuery example here whether it's possible to set the current value of the slider as text that appears on the slider knob.
So, as the user changes the slider, the new value would continually update as a number value displayed as text on the surface of the slider knob in real time.
$(document).ready(function() {
$("#slider").slider();
});
<div id="slider"></div>
Is there a way to do that?
#EvilMM's answer is almost right but s/he forgot the quotes and I've also experienced the slider value being -1 so I wrote in a fix for that.
<div id="slider"></div>
js:
$("#slider").slider({
max: 10,
slide: function (event, ui) {
m_val = ui.value;
if (m_val < 0) {
m_val = 0;
$(this).slider({ value: 0 });
}
$(this).find("a:first").text(m_val);
}
});
Lets say your slider is called "slider", just like in you example:
<div id="slider" class="slider"></div>
Then, inside this div, there is a generated link-tag (a) that represents the knob.
So you could try something like that:
$(document).ready(function() {
$("#slider").slider(
slide: function(event, ui){
$("#slider").find(a:first).text(ui.value);
}
);
});
This should write the current value on the knob while sliding.
What you now have to do, is to play around with the css to format the knob.
I hope this will help a little bit.
If you are using Jquery UI
$(function(){
var slider = $('#slider1').bxSlider({
onBeforeSlide: function(currentSlide, totalSlides){
alert(currentSlide);
}
});
Done!

Categories

Resources