Stop jQuery animate function within setInterval and assign css opacity to 0 - javascript

I have a problem setting opacity to 0 after animate function in jQuery finished changing opacity value from 0 to 1. Any help would be appreciated.
var i = -1;
var interval = setInterval($.proxy(function () {
i++;
if (i >= this.options.slices) {
clearInterval(interval);
this.$element.children("[class='" + this.options.clonesClass + "']" ).css("opacity", 0);
} else {
this.$element.children("[data-index='" + i + "']").stop().animate({ opacity: 1 }, 1000);
}
}, this), 50)

Take a look in animate docs. If what you want to achieve is performing an action after animate completes, then pass a function performing that action as a last argument to animate.
So basically this
this.$element.children("[data-index='" + i + "']").stop().animate({ opacity: 1 }, 1000)
should become something like
this.$element.children("[data-index='" + i + "']").stop().animate({ opacity: 1 }, 1000, function(){
$element.css({opacity:0});
})
Edit:
Working with intervals is not really required with jQuery. Assumming the element you want to animate is $element, just execute
$element.stop().animate({ opacity: 1 }, 1000, function(){
$element.css({opacity:0});
})
Edit:
To achieve what you describe in a comment you need to chain animate calls in a sequence. I would recommend a recursive construct like this (pseudo code):
function myAnimate(elementsArray, num) {
if (num < elementsArray.size) {
$(elementsArray[num]).animate({ opacity: 1 }, 1000, function(){
myAnimate(elementsArray, num + 1);
})
} else {
for each el in elementsArray {
$(el).css({opacity:0});
}
// do other things, like prepare for next iteration
// then maybe call myAnimate(elementsArray, 0)
// to start all over again
}
}
then call it like this
myAnimate($('div.toBeAnimated'), 0)

This is the only way I managed to achieve the result I wanted.
var t = this;
t.$element.children( "[class='" + t.options.clonesClass + "']" ).each( $.proxy( function () {
setTimeout( $.proxy( function () {
i++;
if ( i < t.options.slices ) {
$( this ).animate( { opacity: 1 }, 1000 )
} else {
$( this ).animate( { opacity: 1 }, 1000, function () {
t.$element.children( "[class='" + t.options.clonesClass + "']" ).css( "opacity", 0 );
} );
}
}, this ), timeBuffer );
timeBuffer += 50;
} ), this );

Related

jQuery.animate() in a for loop

I have the following code:
$("." + selectedOption + ":eq(0)").show().animate({
left: 0 + $(".option1:visible").outerWidth(),
opacity: 1
}, 700, function() {
$("." + selectedOption + ":eq(0)").animate({
top: 0
}, 700);
});
This works just as I want it to... but I want to repeat this animation numerous times over, each time animating the next "selectedOption", i.e. :eq(1), :eq(2), :eq(3). So I thought putting the above code within a for loop would work:
for(i = 0; i < 5; i++) {
//code here
}
When I did it doesn't work. Any ideas why?
Thanks
Instead of the foor loop use https://api.jquery.com/each/ and you will need to change that that :eq()
Or simply add class to the item which you have to animate and remove it after finishing it
You need a recursive function. Something like this:
var count = 0;
function animateNextOption() {
$("." + selectedOption + ":eq(" + count++ + ")").show().animate({
left: 0 + $(".option1:visible").outerWidth(),
opacity: 1
}, 700, animateNextOption);
}
animateNextOption();
Try using .queue() , .promise()
var selectedOption = "selectedOption";
$({}).queue("_fx", $.map($("." + selectedOption), function(el) {
return function(next) {
return $(el).animate({
opacity: 1
}, 700, function() {
$(this).animate({
top: 0
}, 700)
}).promise().then(next)
}
})).dequeue("_fx")
.selectedOption {
position: relative;
opacity: 0;
top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="selectedOption">1</div>
<div class="selectedOption">2</div>
<div class="selectedOption">3</div>

jQuery Animated Text Colors

I'm trying to get each letter color to swap from red to green and back to red.
What I have now works, but I don't like the fading, is there a better way to do this?
const ltr = $('h1').text().split('');
function colorChange() {
$( 'h1' ).fadeOut(500, function() {
redGreen();
}).fadeIn(500).fadeOut(500, function() {
greenRed();
}).fadeIn(500);
}
setInterval( function() {
colorChange();
}, 1);
function redGreen() {
$('h1').text('');
for(var i = 0; i < ltr.length; i++) {
if(i % 2 == 0) {
$('h1').append('<span class="red">' + ltr[i] + '</span>');
} else {
$('h1').append('<span class="green">' + ltr[i] + '</span>');
}
}
}
function greenRed() {
$('h1').text('');
for(var i = 0; i < ltr.length; i++) {
if(i % 2 == 0) {
$('h1').append('<span class="green">' + ltr[i] + '</span>');
} else {
$('h1').append('<span class="red">' + ltr[i] + '</span>');
}
}
}
Referred to the solution for toggling class animation here : ToggleClass animate jQuery?. You should change your colorChange function to something like this :
function colorChange() {
$( 'h1 > span' ).toggleClass( "red green", 1000, "easeInOutQuad" );
}
And make sure you build the spans at the beginning with alternative classes to each item (use one of your redGreen() or greenRed() function for the first time only).
Check this Fiddle
You need to include jQuery UI to have the effect.
I managed to remove the fade effect by using setTimeout.
See the plunker here

jQuery animate array skip to last

I am trying to animate an array of images using Jquery. When I have one element in the array it works fine but when I have more then one element it just animates the last element of the array.
I set the src of the img tag and move it to the right. The moveRight function move the image to the right and call moveLeft to move it to the left. The moveLeft function moves the image to the left and fade it.
$.each(imageArray, function (i, val) {
$("#b").attr("src", imageArray[i].src);
moveRight();
}
function moveRight(){
$("#b").animate({left: "+=500"}, 2000, moveLeft)
}
function moveLeft(){
$("#b").animate({left: "-=500"}, 2000,fade)
}
Is there a way each image can be moved right and left / or just left or right instead of having the last one moving only. I am trying to figure out what is wrong with my code.
I think the best thing you can do is to use a recursive method. Here is an example (check jsFiddle):
var MyApp = {
Items: {
Elements: $('div'),
Loaded: 0
},
Start: function(){
if( this.Items.Elements.length == this.Items.Loaded ) return; // return.. or play a sound, then return to stop iterations
this.Items.Elements.eq(this.Items.Loaded).animate({ left: '50%' }, {
duration: 1000,
complete: function(){
MyApp.Items.Loaded++;
MyApp.Start();
}
});
}
};
$(function(){
MyApp.Start();
});
It's an example but you can do it easily by this way.
How about this variant: http://jsbin.com/xezetuboye/1/edit?html,js,output ?
var arr = [
'http://e404.pw/pictures/evernote-logo.png',
'http://e404.pw/pictures/font-face.png',
'http://e404.pw/pictures/html-coder.jpg'
];
var count = 0;
function setImg(){
if(arr.length <= count){ return; }
$("#b").attr("src", arr[count]);
moveRight();
count++;
}
function moveRight(){
$("#b").animate({left: "+=500"}, 2000, moveLeft);
}
function moveLeft(){
$("#b").animate({left: "-=500"}, 2000, setImg);
}
setImg();
Try utilizing .queue(). Note, if changing src of same img element , would have to wait until each image loaded.
var imageArray = [
"http://lorempixel.com/100/100/cats",
"http://lorempixel.com/100/100/animals",
"http://lorempixel.com/100/100/technics",
"http://lorempixel.com/100/100/nature"
];
var b = $("#b");
var cycle = function cycle() {
return b.queue("slide", $.map(imageArray, function(val, i) {
return function(next) {
$(this).fadeOut(50).attr("src", val);
this.onload = function() {
return $(this).fadeIn(50, function() {
return moveRight.call(this).then(function() {
return moveLeft.call(this)
}).then(next);
});
}
}
})).dequeue("slide");
};
function moveRight() {
return $(this).animate({
left: "500"
}, 2000).promise()
}
function moveLeft() {
return $(this).animate({
left: 0
}, 2000).promise()
}
var infiniteCycle = function infiniteCycle() {
return cycle().promise("slide").then(infiniteCycle)
};
infiniteCycle();
#b {
position: relative;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<img id="b" />
Here's a very basic example of what you're trying to achieve. From here you can try and animate the transition, switch it so buttons activate a left/right change. I would suggest playing around with this until you comfortable with the basic functionality. From there you can look into plugins/libraries that can help you. http://jsfiddle.net/306Lqov5/1/
HTML
<img id="b" src="http://placehold.it/100/100&text=Image 1" />
JavaScript
var images = [
'http://placehold.it/100/100&text=Image 1',
'http://placehold.it/100/100&text=Image 2',
'http://placehold.it/100/100&text=Image 3',
'http://placehold.it/100/100&text=Image 4'
];
var index = 1, //start at one since we have the first image in by defualt
img = $('#b');
setInterval(function(){
img.attr('src', images[index]);
index++; //index = index + 1;
if (index == images.length){ //if we've reached the length of the array reset to zero
index = 0;
}
},2000); //switch ever 2 seconds

Pure JavaScript fade in and out - fade in not working

See below snippet. Fade out works fine, but any idea why it won't fade in?
My HTML:
<div id="id10574"><span style="font-size:6em">♥</span></div>
<button id="b1">Fade Out</button>
<button id="b2">Fade In</button>
<script src="fade.js"></script>
and the JS:
var cat = document.getElementById("id10574");
cat.style.opacity = 1;
function fadeout() {
if (cat.style.opacity > 0) {
cat.style.opacity = (cat.style.opacity - 0.01);
setTimeout( fadeout, 10 );
} else {
}
}
function fadein() {
if (cat.style.opacity < 1) {
cat.style.opacity = (cat.style.opacity + 0.01);
setTimeout( fadein, 10 );
} else {
}
}
document.getElementById("b1").addEventListener("click", fadeout , false);
document.getElementById("b2").addEventListener("click", fadein , false);
I'm really stumped on this one. Trying to make a simple effect that will work on IE8 (Sharepoint in corporate environment).
Thanks!
Basically, cat.style.opacity is a string. So cat.style.opacity + 0.01 would be regarded as a string concatenation.
You can do parseFloat(cat.style.opacity) + 0.01 instead
In fact, there are many ways to coerce a string to number. cat.style.opacity - 0.0 as your fadeout(), or even 1.0 * cat.style.opacity
see https://jsfiddle.net/03rzmyL0/
Does this do what you want?
function fadeout() {
setInterval( function(){
cat.style.opacity = (cat.style.opacity - 0.01);
}, 10 );
}
The issue is due to wrong assignment of value to opacity. To as value of style opacity is text you have to parse it to float value and then you can check or assign values properly.
Check Demo here.
var cat = document.getElementById("id10574");
cat.style.opacity = 1;
var fdout, fdin;
function fadeout() {
fdout = setInterval( function(){
if (parseFloat(cat.style.opacity) > 0) {
cat.style.opacity = parseFloat(cat.style.opacity) - 0.01;
} else {
clearInterval(fdout);
}
}, 10 );
}
function fadein() {
fdin = setInterval( function(){
if (parseFloat(cat.style.opacity) < 1) {
cat.style.opacity = parseFloat(cat.style.opacity) + 0.01;
} else {
clearInterval(fdin);
}
}, 10 );
}
document.getElementById("b1").addEventListener("click", fadeout , false);
document.getElementById("b2").addEventListener("click", fadein , false);

Stop timeOut and animation on mouseenter and continue on mouseleave

I wanted to get rid of a slider-plugin, so i tried to build my own,
everything works nice but i´m stuck to stop the whole thing on hover and restart it again on mouseleave,
here is my js :
function startPslider(val) {
if (!val) {
val = 0;
}
var holder = 'slideHolder';
var text = 'slideText';
startInterval(holder, text, val);
}
function startInterval(holder, text, val) {
var t;
var i = val;
if (i > 2) {
i = 0
}
$('#' + holder + i).animate({
opacity: 1,
}, function () {
$(this).addClass('active')
$('.' + text + i).animate({
opacity: 1,
left: 0
}, 1200);
t = setTimeout(function () {
$('.' + text + i).animate({
opacity: 0,
left: '-400px'
}, 1200);
$('#' + holder + i).animate({
opacity: 0,
}, 2200).removeClass('active');
startPslider(i + 1);
}, 4000)
});
// Here´s the not working hover-function
$('#hpCanvas').hover(function () {
clearTimeout(t);
}, function () {
var id = $('.active').attr('id');
var slide = id.substring(11, 22);
console.log(slide)
startPslider(slide);
});
}
$(function () {
startPslider();
});
tryed to solve this with adding class 'active' to the current holder and at hover-out try to catch the current-slide number (val) and restart it again, starting on the correct slide, but it´s not working as I wish,
have a look at this fiddle, http://jsfiddle.net/zDh76/ you will find html and css there, as you see everything works fine as long you do not hover.
Maybe anyone has a helping hint how to stop the animation, clear the timer and go on with the correct slide on mouseleave?
UPDATE
i separated start and end-interval
function startPslider(i) {
if(!i){
i=0;
}
if(i >2){
i=0
}
console.log('started Slider with slide:'+i)
var holder = 'slideHolder';
var text = 'slideText';
startInterval(holder, text, i);
}
function startInterval(holder,text,i) {
var t;
var v;
console.log('started Interval with slide:'+i);
$('#'+holder+i).animate({
opacity:1,
}, function(){
$('.'+text+i).animate({
opacity:1,
left:0
},1200);
t= setTimeout(function(){endInterval(holder,text,i); },4000);
});
}
function endInterval(holder,text,i,cont){
console.log('end Interval with slide:'+i);
$('.'+text+i).animate({
opacity:0,
left:'-400px'
},1200);
$('#'+holder+i).animate({
opacity:0,
},2200, function(){
$('.slideHolder').css('opacity',0);
i = i+1;
startPslider(i);
});
}
I found it out myself,
i needed to unbind the hover event on #hpCanvas inside the mouseleave function like
$('#hpCanvas').hover(function(){
$('.slideHolder, .slideText').stop(true,true);
clearTimeout(t)
},function(){
endInterval(holder,text,i);
$('#hpCanvas').unbind('mouseenter mouseleave')
})
as the next call to bind it with hover event is inside the mouseleave-part of the first hover event.
thanks anyway for everyone reading this

Categories