jQuery Animated Text Colors - javascript

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

Related

trigger function when done airport plugin text effect

I'm using a plugin which rotates letters similar to airport notice boards.
Here is the script written by http://unwrongest.com/projects/airport/
I would like to know how to trigger a function once the rotation of the letter has ended so that I can change the css background property of my background div before the next array starts rotating.
Something like so: background1 -> rotate "7 days" -> done rotation -> background2 -> rotate "14 days" -> done rotation -> background3 -> rotate "22 days" etc...
HTML
$('.dur').airport(['7 days','14 days','22 days','31 days','3 weeks','2 months']);
JS Script
(function($){
$.fn.extend({
airport: function(array) {
var self = $(this);
var chars = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g',' ','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','-','1','2','3','4','5','6','7','8','9','0'];
var longest = 0;
var items = items2 = array.length;
function pad(a,b) { return a + new Array(b - a.length + 1).join(' '); }
$(this).empty();
while(items--)
if(array[items].length > longest) longest = array[items].length;
while(items2--)
array[items2] = pad(array[items2],longest);
spans = longest;
while(spans--)
$(this).prepend("<span class='c" + spans + "'></span>");
function testChar(a,b,c,d){
if(c >= array.length)
setTimeout(function() { testChar(0,0,0,0); }, 0);
else if(d >= longest)
setTimeout(function() { testChar(0,0,c+1,0); }, 10000);
else {
$(self).find('.c'+a).html((chars[b]==" ")?" ":chars[b]);
setTimeout(function() {
if(b > chars.length){
testChar(a+1,0,c,d+1);
}
else if(chars[b] != array[c].substring(d,d+1)){
testChar(a,b+1,c,d);
}
else{
testChar(a+1,0,c,d+1);
}
}, 1);
}
}
testChar(0,0,0,0);
}
});
})(jQuery);
The following conditional
else if(d >= longest)
setTimeout(function() { testChar(0,0,c+1,0); }, 10000);
is where the plugin prepares the next spin after completing one - so you could apply a class/call a function there.
Add brackets and include the logic to apply a class, like this:
else if(d >= longest) {
$('.dur').attr('class', 'dur ' + (colors[c]));
setTimeout(function() { testChar(0,0,c+1,0); }, 1000);
}
Here's a codepen example: http://codepen.io/anon/pen/gbqqKX

how do I cycle through background images by clicking a button?

I want to preview some backgrounds by using a button to cycle through them, just not very good at the js. I have them named "1"-"13". I wanted to step through them. When I get to "13" I want it to set it back to "1" when "next" is clicked and when "prev" is clicked when it gets to "1" to set it to "13". This is what I've tried but I know my syntax is wrong for the js.
HTML
<button id="n" class="b">NEXT</button>
<button id="p" class="b">PREV</button>
CSS
body {
background:black;
}
.b {
background:black;
color:white;
}
JS
$(document).ready(function(){
var i = 1;
$("#n").click(function() {
alert(i);
i++;
$('body').css("background-image", "url(../images/bg/ " + i + " .png)");
if (i===14){i=1;};
});
$("#p").click(function() {
alert(i);
i--;
$('body').css("background-image", "url(../images/bg/ " + i + " .png)");
if (i===0){i=13;};
});
});
Still working on it but some help would be nice getting it done faster.
http://jsfiddle.net/80nz56wy/ I guess a jsfiddle won't help much if I'm using local content.
You should also try this. Here conditions are written before setting CSS, which will check first and then assign the image path.
$(document).ready(function() {
var i = 0;
$("#n").click(function() {
i++;
if (i > 13){ i = 1; };
$('body').css('background-image', 'url(images/bg/' + i + '.png)');
//if (i === 13){ i = 1; };
});
$("#p").click(function() {
i--;
if (i <= 0) { i = 13; };
$('body').css('background-image', 'url(images/bg/' + i + '.png)');
//if (i === 1) { i = 13; };
});
});
Other wise you may get wrong image paths, something like:
images/bg/0.png
or
images/bg/-1.png
Change Your javascript coding as below..
var i = 1;
$("#n").click(function() {
$('body').css("background-image", "bg" + i +".png");
i=i+1;
if (i==13){i=1};
});
$("#p").click(function() {
$('body').css("background-image", "bg" + i +".png");
i=i-1;
if (i==1){i=13};
});
Here it is, not sure what I changed the 20 times I edited the same line over and over but I must have gone full retard earlier.
$(document).ready(function(){
var i = 0;
$("#n").click(function() {
i++;
if ( i > 13 ){ i = 1; };
$('body').css('background-image', 'url(images/bg/' + i + '.png)');
});
$("#p").click(function() {
i--;
if ( i <= 0 ){ i = 13; };
$('body').css('background-image', 'url(images/bg/' + i + '.png)');
});
});

jQuery bug when using bounce effect

I have problem with jQuery bounce effect. Every thing works good when there is no bounce - with bounce, when You move very fast many times on button - in sometime, box just doesn't hide. What is wrong in this jsfiddle?
My jsfiddle:
http://jsfiddle.net/d6mSA/170/
My JS:
$('.flex_section').delegate('a','mouseenter mouseleave',function(e){
var a = $(this).attr('id');
if (e.type == 'mouseenter'){
clearTimeout(t_on)
if (a == 'abc'){
clearTimeout(t_off)
t_on = setTimeout(function() { popup_show(a,t_on); }, 10);
}
} else {
t_off = setTimeout(function() { popup_remove(a,t_off); }, 1000);
}
)}
function popup_show(type,string){
if (type == 'abc'){
$('#pc_' + type).css('display','block');
$('#pc_' + type).effect( "bounce",{times:3,distance:20},1000);
}
clearTimeout(string);
}
function popup_remove(type,string){
$('#pc_' + type).css('display','none');
clearTimeout(string)
}
Keep it simple:
function popup(){
$('.flex_top a').hover(function(){
var type = $(this).attr('id');
var offset = $('#' + type).offset();
$('#id_' + type).css('display','block')
.offset({left:offset.left + 100, top:offset.top + 380})
.effect( "bounce",{times:3,distance:20},1000);
},function(){
var type = $(this).attr('id');
$('#id_' + type).fadeOut();
}
);
}
And dont call many times the same object search $('#id_' + type)
Try using stop
$('#pc_' + type).stop().effect( "bounce",{times:3,distance:20},1000);

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

jQuery / Javascript - loop

I want to make it so when I click somewhere in my website, the background changes. I have three backgrounds, and I want to make a loop of them.
$(document).ready(function() {
$('body').click((function(){
return function()
{
if (counter == null) {
var counter = 1;
}
if(counter == 3) {
$(this).css("background-image","url(3.jpg)");
$(this).css("background-position","10% 35%");
var counter = null;
}
if(counter == 2) {
$(this).css("background-image","url(2.jpg)");
$(this).css("background-position","10% 35%");
var counter = 3;
}
if(counter == 1) {
$(this).css("background-image","url(1.jpg)");
$(this).css("background-position","40% 35%");
var counter = 2;
}
}
})());
});
Why doesn't this work?
Your counter variable isn't scoped right, you need one counter variable. Overall though, why not let .toggle() manage this for you? Here's what it would look like:
$(function() {
$('body').toggle(function(){
$(this).css({"background-image":"url(1.jpg)", "background-position":"40% 35%"});
}, function() {
$(this).css({"background-image":"url(2.jpg)", "background-position":"10% 35%"});
}, function() {
$(this).css({"background-image":"url(3.jpg)", "background-position":"10% 35%"});
});
});
Although the name and common usages suggest that .toggle() only takes 2 functions, it actually takes 2 or more and will cycle through them.
this no longer refers to the body element, it refers to the anonymous function.
Does this code work?
var counter = 1;
$(document).ready(function() {
$('body').click(function() {
if (counter == null) {
counter = 1;
}
if (counter == 3) {
$(this).css("background-image", "url(3.jpg)");
$(this).css("background-position", "10% 35%");
counter = 1;
}
if (counter == 2) {
$(this).css("background-image", "url(2.jpg)");
$(this).css("background-position", "10% 35%");
counter = 3;
}
if (counter == 1) {
$(this).css("background-image", "url(1.jpg)");
$(this).css("background-position", "40% 35%");
counter = 2;
}
});
});
Your function uses this which is refering to itself, not the element. This would fix it:
$('body').click((function(){
var $this = $(this);
return ... {
$this // use $this instead of $(this)
Also, have a look on jQuery .toggle
Your counter declarations are strewn all over the place which makes it difficult to follow what's happening. Further, counter is declared local to the callback function, which means it loses its value every time the function executes.
Here's a simpler solution:
$(function() { // this is equivalent to $(document).ready(...)
var counter = 0;
var images = [
[ '1.jpg', '40% 35%' ],
[ '2.jpg', '10% 35%' ],
[ '3.jpg', '10% 35%' ]
];
$('body').click(function() {
$(this).css('background-image', 'url(' + images[counter][0] + ')');
$(this).css('background-position', images[counter][1]);
// increment counter, wrapping over to 0 when it reaches end of array
counter = (counter + 1) % images.length;
});
});
You can easily extend to this to any number of images by simply adding more entries to the images array.
$(document).ready(function () {
function changeBgImage() {
var imgs = [
["1.jpg", "10% 35%"],
["2.jpg", "10% 35%"],
["3.jpg", "40% 35%"]
];
var counter = 0;
return function() {
$(this).css({
"backgroundImage": "url(" + imgs[counter][0] + ")",
"backgroundPosition": imgs[counter][1]
});
counter += 1;
if (counter === imgs.length) { counter = 0; }
};
}
$('body').click(changeBgImage());
});
Update:
OK, so here we have another solution. It is basically Nick's answer but without redundancy.
$(function () {
var imgs = [["1.jpg", "10% 35%"], ["2.jpg", "10% 35%"], ["3.jpg", "40% 35%"]];
var i = 0;
$("body").click(function () {
$(this).css({"background-image": "url(" + imgs[i][0] + ")", "background-position": imgs[i][1]});
if (++i === imgs.length) { i = 0; }
});
});

Categories