I hope to create a text transition animation using JQuery and have run into an issue of timing. I've looked around some other threads and have not been able to figure out the proper solution to what I am trying to accomplish. Here is the HTML I have:
<div id="t1">
<span>T</span>
<span>H</span>
<span>I</span>
<span>S</span>
</div>
<div id="t2">
<span>T</span>
<span>H</span>
<span>A</span>
<span>T</span>
</div>
JS:
function showMessage(obj, up){
if(dir){
$(obj).children().each(function(i, el) {
setTimeout(function() {
$(el).animate({
'opacity': 1.0,
'top': '0px'
}, 450);
}, 500 + (i * 150));
});
} else {
$(obj).children().each(function(i, el) {
setTimeout(function() {
$(el).animate({
'opacity': 0,
'top': '-30px'
}, 450);
}, 3000 + (i * 150));
});
}
}
showMessage("#t1", true);
showMessage("#t1", false);
showMessage("#t2", true);
showMessage("#t2", false);
Both THIS and THAT are being displayed at the same time. How can I make it so the second isn't displayed until the first has completely disappeared?
demo: jsfiddle
can you chain them?
showMessage("#t1", true, function(){
showMessage("#t1", false, function(){
showMessage("#t2", true, function(){
showMessage("#t2", false, function(){});
});
});
});
and then include counters in your showMessage to check if all the spans have been displayed
function showMessage(obj, up, callback){
var counter = 1;
var numberOfChildren = $(obj).children().size();
if(up){
$(obj).children().each(function(i, el) {
setTimeout(function() {
$(el).animate({
'opacity': 1.0,
'top': '0px'
}, 450, function(){
counter++;
console.log(counter);
if ( counter == numberOfChildren )
{
callback();
}
});
}, 500 + (i * 150));
});
}
else {
$(obj).children().each(function(i, el) {
setTimeout(function() {
$(el).animate({
'opacity': 0,
'top': '-30px'
}, 450, function(){
counter++;
console.log(counter);
if ( counter == numberOfChildren )
{
callback();
}
});
}, 3000 + (i * 150));
});
}
}
$(function() {
showMessage(".dev", true, function(){
showMessage(".dev", false, function(){
showMessage(".dev2", true, function(){
showMessage(".dev2", false, function(){});
});
});
});
});
updated dir to up.
setTimeout is performed under vacuum. Anonymous function does not know about your external variables i and el
Try substituting .delay() for setTimeout , calling second set of animations when i is equal to total .length of first set of animations within .each() called on #t1 .children() : span elements
function showMessage(obj, dir) {
var first = obj[0], second = obj[1];
$(first).children().each(function(i, el) {
$(el).delay(500 + (i * 150)).animate({
"opacity": 1.0,
"top": "0px"
}, 450, function() {
// when all `first` : `#t1` `span` animations complete,
// call `next` with `second`:`#t2` as parameter
if (i === first.length) next(second)
});
});
var next = function(elems) {
$(elems).children().each(function(i, el) {
$(el).delay(3000 + (i * 150)).animate({
"opacity": 0,
"top": "-30px"
}, 450);
});
}
}
showMessage(["#t1", "#t2"]);
#t1 span {
opacity: 0;
top: 30px;
}
#t2 span {
opacity: 1;
top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="t1">
<span>T</span>
<span>H</span>
<span>I</span>
<span>S</span>
</div>
<div id="t2">
<span>T</span>
<span>H</span>
<span>A</span>
<span>T</span>
</div>
Related
Iam using jquery to animate an image to make a mixed up image that scrolls different parts when clicked.
I thought of doing like this
$("#head").click(function () {
if (headclix < 9) {
$("#head").animate({
left: "-=367px"
}, 500);
headclix++;
} else {
$("#head").animate({
left: "0px"
}, 500);
headclix = 0;
}
});
$("#eyes").click(function () {
if (eyeclix < 9) {
$("#eyes").animate({
left: "-=367px"
}, 500);
eyeclix++;
} else {
$("#eyes").animate({
left: "0px"
}, 500);
eyeclix = 0;
}
});
$("#nose").click(function () {
if (noseclix < 9) {
$("#nose").animate({
left: "-=367px"
}, 500);
noseclix++;
} else {
$("#nose").animate({
left: "0px"
}, 500);
noseclix = 0;
}
});
$("#mouth").click(function () {
if (mouthclix < 9) {
$("#mouth").animate({
left: "-=367px"
}, 500);
mouthclix++;
} else {
$("#mouth").animate({
left: "0px"
}, 500);
mouthclix = 0;
}
});
I hope there is better way of doing it
I'm thinking I can do something with the class and each but not sure how to quite make it work. need to make it a click event and keep track of each image part
$(".face").each(function (i) {
if (i < 9) {
$(".face").parent().animate({
left: "-=367px"
}, 500);
i++;
} else {
$(".face").parent().animate({
left: "0px"
}, 500);
i = 0;
}
});
HTML:
<div id="pic_box">
<div id="head" class="face"><img src="images/headsstrip.jpg"></div>
<div id="eyes" class="face"><img src="images/eyesstrip.jpg"></div>
<div id="nose" class="face"><img src="images/nosesstrip.jpg"></div>
<div id="mouth" class="face"><img src="images/mouthsstrip.jpg"></div>
</div>
image in this link will give you an idea of the functionality
Thank you.
You can create a face object that holds the click counts of each face part and also a function to handle the click event (named clickHandler below). The clickHandler takes in an id and calls the appropriate animate function on the element that has that id.
Check below:
var face = {
"headClicks" : 0,
"eyesClicks" : 0,
"noseClicks" : 0,
"mouthClicks" : 0,
"clickHandler" : function(id) {
if(this[id+"Clicks"] < 9) {
animateLeft367(id);
this[id+"Clicks"]++;
} else {
animateLeft0(id);
this[id+"Clicks"] = 0;
}
}
}
function animateLeft367(id) {
$("#" + id).animate({left: "-=367px"}, 500);
console.log('animated ' + id + ' 367');
}
function animateLeft0(id) {
$("#" + id).animate({left: "0px"}, 500);
console.log('animated ' + id + ' 0');
}
$(".face").click(function() {
face.clickHandler(this.id);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="pic_box">
<div id="head" class="face"><img src="images/headsstrip.jpg"></div>
<div id="eyes" class="face"><img src="images/eyesstrip.jpg"></div>
<div id="nose" class="face"><img src="images/nosesstrip.jpg"></div>
<div id="mouth" class="face"><img src="images/mouthsstrip.jpg"></div>
</div>
I am dealing with following jquery which contains multiple image animations.My query is, through setInterval, my animation is not run step by step and it doesn't maintain interval sometimes. Sometimes my 1st animation and 2nd animation runs together. How can I resolve it and run my all three animation step by step in specific interval? Can we use setTimeout? if yes then how? Please excuse me if I wrote incorrect interval time in following jquery as I am beginner in jquery.
$(document).ready(function() {
var runAnimate1 = true;
var runAnimate2 = false;
var runAnimate3 = false;
setInterval(function() {
if (runAnimate1) {
$("#animate1").fadeIn('slow').animate({
'display': 'inline-block',
'margin-left': '220px',
'margin-bottom': '20px'
}, 500, function() {
$('.1st').animate({
'opacity': '0'
}, 1000, function() {
$('.1st').animate({
'opacity': '1'
})
})
}).fadeOut();
$("#animate1").fadeIn('slow').animate({
'margin-bottom': '0px',
'margin-left': '-140px'
}, 1000, function() {
runAnimate1 = false;
runAnimate2 = true;
runAnimate3 = false;
}).fadeOut('slow');
}
if (runAnimate2) {
$(".2nd").fadeIn('slow').animate({
'margin-left': '150px',
'margin-bottom': '2px'
}, 600, function() {
$('.1st').animate({
'opacity': '0'
}, 1000, function() {
$('.1st').animate({
'opacity': '1'
}, 1000)
})
}).fadeOut();
$(".2nd").fadeIn('slow').animate({
'margin-bottom': '0px',
'margin-left': '-150px'
}, 1000, function() {
runAnimate1 = false;
runAnimate2 = false;
runAnimate3 = true
}).fadeOut('slow');
}
if (runAnimate3) {
$('.3rd').fadeIn('slow').animate({
'display': 'inline-block',
'margin-left': '220px',
'margin-bottom': '2px'
}, 1000, function() {
$('.1st').animate({
'opacity': '0'
}, 1000, function() {
$('.1st').animate({
'opacity': '1'
})
})
}).fadeOut('slow');
$('.3rd').fadeIn('slow').animate({
'margin-bottom': '0px',
'margin-left': '-220px'
}, 1000, function() {
runAnimate1 = true;
runAnimate2 = false;
runAnimate3 = false;
}).fadeOut('slow');
}
}, 6000);
});
My html is as follow:
<div id="outer-box" class="1st">
<img class="1st" src="img/sofa2.jpg">
<div id="animate1" style="display: none; position: absolute; bottom: 0; left: 0;">
<img class="1st" src="img/chotu.png" style="height:300px; width:200px;" />
</div>
<div class="2nd 1st" style="display:none; position:absolute; bottom:0; left:0">
<img src="img/hand.png" style="width:200px; height:300px;">
</div>
<div class="3rd 1st" style="display:none; position:absolute; bottom:0; left:0">
<img src="img/handyh.png" style="width:180px; height: 150px;">
</div>
</div>
If you store the setInterval in a variable you will be able to change it.
To change the time one possible solution is:
var interval = setInterval(functionName,3000);
function changeTime(newTime) {
clearInterval(interval);
interval = setInterval(functionName,newTime);
}
I am trying to animate divs. The idea is that when the customer has scrolled until the div it become animated... and if the customer scroll back to the top of the page this the div run the action opposite to the first animation (like a fadein/out)
Well the point is that after the first animation, the second one never run.
This is my code:
<div class="wrapper">
<div class="face_content">
<img src="img/face.jpg">
</div>
<div class="face_text">
<p>some text here</p>
</div>
</div>
And then I am trying this javascript with jquery
var face_dist = $('.wrapper').offset().top;
$(window).scroll(function () {
//show the face
var face_diff = face_dist - $(window).scrollTop();
if(face_diff < 200) {
show_sch();
}
if($('.face_content').hasClass('showing')) {
if(face_diff > 200) {
hide_sch();
}
}
});
function show_sch() {
$('.face_content img').animate({
'opacity': 1,
'right': 0
},1000, function() {
$('.face_content').addClass('showing');
});
$('.face_text ul').animate({
'opacity': 1,
'left': 0
},1000);
}
function hide_sch() {
$('.face_content img').animate({
'opacity': 0,
'right': 80
},1000);
$('.face_text ul').animate({
'opacity': 0,
'left': 80
},1000);
}
Any idea? (the first animation run properly but the second one no at all.
The issue is because your face_diff value is never more than 200, but smaller than -200. And you animate is played a lot of time. You can control this with a check if active.
Please try below
var face_dist = $('.wrapper').offset().top;
var active = 0;
$(window).scroll(function () {
//show the face
var face_diff = face_dist - $(window).scrollTop();
if(face_diff < 200 && face_diff >= 0) {
if(active==0){
active=1;
show_sch();
}
}
if($('.face_content').hasClass('showing')) {
if(face_diff < -200) {
if(active==0){
active=1;
hide_sch();
}
}
}
});
function show_sch() {
$('.face_content img').animate({
'opacity': 1,
'right': 0
},1000, function() {
$('.face_content').addClass('showing');
active=0;
});
$('.face_text ul').animate({
'opacity': 1,
'left': 0
},1000,function(){
active=0;
});
}
function hide_sch() {
$('.face_content img').animate({
'opacity': 0,
'right': 80
},1000,function(){
active=0;
});
$('.face_text ul').animate({
'opacity': 0,
'left': 80
},1000,function(){
active=0;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="face_content">
<img style="opacity:0" src="https://www.dpreview.com/files/p/articles/7192167506/images/intro.jpeg">
</div>
<div class="face_text">
<p>some text here</p>
</div>
</div>
I have three boxes and now, there are working as i expected. But, I need this work automatically every 30 secs without 'click' event. Please see this fiddle http://jsfiddle.net/ykbgT/8493/. Any idea?
code as below
<div id="box1" class="box">Div #1</div>
<div id="box2" class="box">Div #2</div>
<div id="box3" class="box">Div #3</div>
$('.box').click(function () {
$('.box').each(function () {
if ($(this).offset().left < 0) {
$(this).css("left", "150%");
} else if ($(this).offset().left > $('.box').width()) {
$(this).animate({
left: '50%',
}, 500);
} else {
$(this).animate({
left: '-150%',
}, 500);
}
});
});
You can use a javascript method called setinterval();
setInterval() - executes a function, over and over again, at specified
time intervals.
JSFIDDLE DEMO
setInterval(function(){
$('.box').each(function() {
if ($(this).offset().left < 0) {
$(this).css("left", "150%");
} else if ($(this).offset().left > $('.box').width()) {
$(this).animate({
left: '50%',
}, 500 );
} else {
$(this).animate({
left: '-150%',
}, 500 );
}
});
}, 30000);
setInterval(function() {
$('.box').each(function() {
if ($(this).offset().left < 0) {
$(this).css("left", "150%");
} else if ($(this).offset().left > $('.box').width()) {
$(this).animate({
left: '50%',
}, 500);
} else {
$(this).animate({
left: '-150%',
}, 500);
}
});
}, 30000);
I am trying to impliment tweet scroller on http://www.hubspot.com/
which is i guess using tweet-scroller from http://code.divshot.com/tweetscroller/
but this link is broken as demo is not working.
i looked for alternative.
I found http://jsfiddle.net/doktormolle/4c5tt/
HTML:
<ul class="slide">
<li><img src="http://www.google.com/logos/2010/canadianthanksgiving2010-hp.jpg"/></li>
<li><img src="http://www.google.com/logos/2010/germany10-hp.gif"/></li>
<li><img src="http://www.google.com/logos/stpatricks_02.gif"/></li>
</ul>
CSS:
ul.slide{margin:0;
padding:0;
height:80px;
list-style-type:none;}
ul.slide li{float:left;
list-style-type:none;}
ul.slide img{border:1px solid silver;
height:80px;}
JS:
//Plugin start
(function ($) {
var methods = {
init: function (options) {
return this.each(function () {
var _this = $(this);
_this.data('marquee', options);
var _li = $('>li', _this);
_this.wrap('<div class="slide_container"></div>')
.height(_this.height())
.hover(function () {
if ($(this).data('marquee').stop) {
$(this).stop(true, false);
}
},
function () {
if ($(this).data('marquee').stop) {
$(this).marquee('slide');
}
})
.parent()
.css({
position: 'relative',
overflow: 'hidden',
'height': $('>li', _this).height()
})
.find('>ul')
.css({
width: screen.width * 2,
position: 'absolute'
});
for (var i = 0; i < Math.ceil((screen.width * 3) / _this.width()); ++i) {
_this.append(_li.clone());
}
_this.marquee('slide');
});
},
slide: function () {
var $this = this;
$this.animate({
'left': $('>li', $this).width() * -1
},
$this.data('marquee').duration,
'swing',
function () {
$this.css('left', 0).append($('>li:first', $this));
$this.delay($this.data('marquee').delay).marquee('slide');
}
);
}
};
$.fn.marquee = function (m) {
var settings = {
'delay': 2000,
'duration': 900,
'stop': true
};
if (typeof m === 'object' || !m) {
if (m) {
$.extend(settings, m);
}
return methods.init.apply(this, [settings]);
} else {
return methods[m].apply(this);
}
};
})(jQuery);
//Plugin end
//call
$(document).ready(
function () {
$('.slide').marquee({
delay: 3000
});
}
);
which works fine with little modification i did
http://jsfiddle.net/3pZwR/1/
only problem is it stops after each div is scrolled.
I want it to be infinite scroll like effect without getting it stopped. like on hubspot.
You should use another JQuery Easing method instead of "swing".
Have a look at the Easings on the JQuery website: http://api.jqueryui.com/easings/