Javascript how do I use a while loop on this animation? - javascript

I've been working with javascript for a few days now but I'm currently stuck on while looping/using switches this animation.
essentially the program will "level up" into a new colored image after moving 3 times, and start from the beginning. I have a gold level up so far, but I want to keep changing colors for the next level ups. I'm trying to add a new classlist to the animated image, a different one for every counter, but nothing seems to be working. this is how I have it:
$("#go").click(function() {
var dest = parseInt($("#block").css("margin-left").replace("px", "")) + 100;
if (dest < 400) {
$("#block").animate({
marginLeft: dest + "px"
}, 700);
} else {
$("#block").animate({
marginLeft: "10px"
}, 100);
//if counter = 1
document.getElementById('block').classList.add("gold")
//if counter = 2
//document.getElementById('block').classList.remove("gold")
//document.getElementById('block').classList.add("pink")
//... etc
//counter += 1
}
});
and here is the link to run the program (click the run text)
http://jsfiddle.net/mept9g1u/
Hope someone can help!

You need to initialise your counter variable to 0 outside of the click event listener, otherwise it's reset to 0 every time you click.
var counter = 0 // ⭐️ Declare counter here
$("#go").click(function() {
var dest = parseInt($("#block").css("margin-left").replace("px", "")) + 100;
if (dest < 400) {
$("#block").animate({ marginLeft: dest + "px" }, 700);
} else {
$("#block").animate({ marginLeft: "10px" }, 100);
counter++;
if (counter === 1) {
document.getElementById('block').classList.add("gold")
}
if (counter === 2) {
document.getElementById('block').classList.remove("gold")
document.getElementById('block').classList.add("pink")
}
// etc.
}
});

$(document).ready(function(){
function BoxAnimate(){
var count= 0;
while( count < 6){
$(".boxanimate").eq(count).stop(true, true).delay(1000*count).animate({
left:"400px"
});
count++;
}
}
BoxAnimate();
});
.boxanimate { background:Green;
margin-bottom:10px;
margin-left:30px;
height:150px;
width:150px;
font-family:Arial;
font-size:30px;
text-align:center;
color:#fff;
line-height:150px;
position:relative;
clear:both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ani-wrp">
<div class="boxanimate"> data1 </div>
<div class="boxanimate"> data2 </div>
<div class="boxanimate"> data3 </div>
<div class="boxanimate"> data4 </div>
<div class="boxanimate"> data5 </div>
</div>

Related

Slot Machine simultaneous jQuery animation not working

I'm trying to create Slot Machine effect for lottery.
The target numbers will be already set, so that once the stop button is pressed it should stop on that number.
Everything is working fine for slot 1. But if I add the same code for slot 2 and slot 3 then it's creating the problem.
Below given is the code:
$(document).ready(function() {
s1 = 1;
s2 = 1;
s3 = 1;
num1 = 6;
num2 = 5;
num3 = 7; //Target for 3 slots
i = 100; //Top margin for animation
$('#start').click(function() {
animateslot(50, 0);
});
$("#stop").click(function() {
stopanimationslot1(50, 0);
});
});
function animateslot(d = 150, i = 0) {
i = i + 100;
$('#slot1').animate({
marginTop: -i
}, {
duration: d,
complete: function() {
$("#slot1").append("<h3>Column " + s1 + "</h3>");
s1++;
if (s1 > 9) {
s1 = 1;
}
console.log(s1);
animateslot(d, i);
}
});
//If below given code is added it doesn't work**
/*
$('#slot2').animate(
{
marginTop: -i
},
{
duration: d,
complete: function() {
$("#slot2").append("<h3>Column "+s2+"</h3>");
s2++;
if(s2>9){
s2 = 1;
}
console.log("s2="+s2);
animateslot(d, i);
}
}
);
*/
}
function stopanimationslot1(d = 150, i = 0, num = 1) {
$('#slot1').stop();
i = i + 100;
$('#slot1').animate({
marginTop: -i
}, d, function() {
if (Math.abs(i / 100) == num1) {
$('#slot1').clearQueue().stop(false, true);
console.log("finished");
} else {
$("#slot1").append("<h3>Column " + s1 + "</h3>");
s1++;
if (s1 > 9) {
s1 = 1;
}
stopanimationslot1(d + 50, i, num);
}
});
}
#slot1 h3,
#slot2 h3,
#slot3 h3 {
width: 100px;
height: 100px;
border: 1px solid #999;
margin: 0;
}
#slotmachine {
max-height: 100px;
overflow: hidden;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Start<br><br>
Stop<br><br>
<div class="container">
<div class="row" id="slotmachine">
<div class="col-sm-4" id="slot1">
<h3>Column 1</h3>
</div>
<div class="col-sm-4" id="slot2">
<h3>Column 1</h3>
</div>
<div class="col-sm-4" id="slot3">
<h3>Column 1</h3>
</div>
</div>
</div>
Also can be found here: https://jsfiddle.net/sushanttayade123/fqkgvu59/
The reason why it's not working as expected lies in animateslot(d, i);.
After pressing start:
Slot 1 completes and calls animateslot()
Slot 2 completes and also calls animateslot()
On the next "animation cycle", the method will not run once as it did before, but twice, which results in the stuttery behaviour. The amount of calls will constantly grow at a factor of two for every cycle.
To fix this, either call animateSlot() once after all animations have completed or move every slot into it's own function (animateSlot1(), animateSlot2(), ...).
A word of advice at the end: I wouldn't recommend adding a new node after every spin, as this can cause performance drops.

Slide div every click once right and then on same click back again(left)

My div goes right but when i click again should be back to its original location.....
i tried many stuff but not working.Here is my code...
How do i reverse it when clicked. on every click it should be the reverse of the previous action i.e.
if on click the div moves right then on next click at the same location it should move left similar to a pendulum
<html>
<head><title></title>
<script type="text/javascript" language="javascript">
//<![CDATA[
window.onload=function()
{
document.getElementById("d2").onclick = slideIt;
};
function slideIt()
{
var slidingDiv = document.getElementById("d1");
var stopPosition = 50;
if (parseInt(slidingDiv.style.left) < stopPosition )
{
slidingDiv.style.left = parseInt(slidingDiv.style.left) + 2 + "px";
setTimeout(slideIt, 1);
}
/*
if(parseInt(slidingDiv.style.left) > stopPosition )
{
slidingDiv.style.left = parseInt(slidingDiv.style.left) + 2 + "px";
setTimeout(slideIt, 1);
}*/
}
//]]>
</script>
</head>
<body>
<div id="d1" style="position:absolute; left:-131px;">
<div style=" float:left" >click here to slide the div</div>
<div id="d2" style=" float:left" >click here to slide the div</div> </div>
</body>
</html>
Change your JavaScript with this one
<script type="text/javascript" language="javascript">
$(document).ready(function(){ $("#d2").click(function(){
if($("#d1").css("left") <="-131px")
{
$("#d1").animate({left:'250px'});
}
else {
$("#d1").animate({left:'-131px'});
}
});
});
</script>
This will work fine
Good Luck..
Okay, so here's how I have done things...
DEMO: http://jsfiddle.net/xDDX8/2/
HTML
<div id="d1">
<div id="d2">click here to slide the div</div>
</div>
CSS
#d1 {
position: absolute;
border: 1px solid red;
cursor: pointer;
left: 0;
}
.moveLeft {
color: blue;
}
.moveRight {
color: lime;
}
Javascript
window.onload = bindEvents();
function bindEvents() {
document.getElementById('d2').onclick = slideIt;
}
// Global variables
var slidingDiv = document.getElementById('d1'); // Cache the element
var timeout = 0;
var minPosition = 0;
var maxPosition = 50;
function slideIt() {
// Work out current position
var currentPosition = slidingDiv.offsetLeft;
// Check which direction to move
if (hasClass(slidingDiv, 'moveRight'))
{
// Have we hit our movement limit?
if (currentPosition <= minPosition)
{
// remove all classes and set a class to move the other direction
slidingDiv.removeAttribute('class');
slidingDiv.setAttribute('class', 'moveLeft');
// Clear our timeout
clearTimeout(timeout);
}
else
{
// Still space to move so let's move a few pixels (-)
slidingDiv.style.left = (currentPosition - 2) + "px";
timeout = setTimeout(slideIt, 1);
}
}
else // all comments as above really
{
if (currentPosition >= maxPosition)
{
slidingDiv.removeAttribute('class');
slidingDiv.setAttribute('class', 'moveRight');
clearTimeout(timeout);
}
else
{
slidingDiv.style.left = (currentPosition + 2) + "px";
timeout = setTimeout(slideIt, 1);
}
}
}
// Function to test whether an element has a specific class
// https://stackoverflow.com/questions/5898656/test-if-an-element-contains-a-class
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

setInterval and Switch Between Divs

I'm trying to switch between divs at an interval, but also be able to stop it in order to include the ability to switch on command with an arrow button on the screen. (Like a slideshow of divs with an arrow to switch immediately.)
Therefore, I cannot use .delay(), as it cannot be stopped, so I'm trying to use .setTimeout, but I'm failing miserably. Can someone tell me what I'm doing wrong?
var divs = $('div[id^="Frame"]').hide(),
i = 0;
(function cycle() {
divs.eq(i).fadeIn(1000)
.setTimeout(function(){divs.eq(i).fadeOut(1000, cycle);},2000);
i = ++i % divs.length; // increment i,
// and reset to 0 when it equals divs.length
})();
I'm not sure what you are trying to achieve, but here is some code which will fadein/fadeout the divs and you have a chance to stop the process:
var divs = $('div[id^="Frame"]').hide(),
i = 0,
currentDiv = null,
interval = null;
var stopFading = function() {
clearTimeout(interval);
}
var showDiv = function() {
if(currentDiv) {
currentDiv.fadeOut(1000, function() {
currentDiv = null;
showDiv();
});
} else {
currentDiv = divs.eq(i);
currentDiv.fadeIn(1000, function() {
interval = setTimeout(showDiv, 2000);
});
i += 1;
if(i > divs.length) i = 0;
}
}
showDiv();
LIVE DEMO
JS:
var H = $('#FrameHolder'),
D = $('#Frame > div'),
B = $('#Button'),
n = D.length,
f = 400, // fade time
p = 2500,// pause
c = 0, // counter
i; // interval
function loop(){
i = setInterval(function(){B.click();},p);
}loop();
H.hover(function(e){
var mEnt = e.type.match('t');
B.stop().fadeTo(f,!!mEnt);
return mEnt?clearInterval(i):loop();
});
B.click(function(){
D.stop().fadeOut(f).eq(++c%n).fadeIn(f);
});
HTML:
<div id="FrameHolder">
<div id="Frame">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<div id="Button"></div>
</div>
CSS:
#FrameHolder{
position:relative;
margin:0 auto;
width:400px;
height:300px;
overflow:hidden;
}
#frame{
}
#Frame > div{
position:absolute;
top:0;
text-align:center;
line-height:276px;
width:400px;height:300px;
}
#Frame > div + div{
display:none; /* hide all but 1st */
}
#Button{
cursor:pointer;
position:absolute;
width:60px;
height:60px;
background:rgba(0,0,0,0.5);
border-radius:50%;
right:20px;
top:50%;
margin-top:-30px;
display:none;
}
Haven't taken a look to see if the rest of your code is working, but the immediate error is that setTimeout is not chainable. So the code should look like this...
EDIT -- SHOULD WORK
The other issue was that the increment of i needed to be done in the setTimeout otherwise, i would be incremented before the function ran
http://jsfiddle.net/RJe86/1/
var divs = $('div[id^="Frame"]').hide(),
i = 0;
(function cycle() {
divs.eq(i).fadeIn(1000,function(){
setTimeout(function(){
divs.eq(i).fadeOut(1000, cycle);
i = ++i % divs.length; // increment i,
// and reset to 0 when it equals divs.length
},2000);
});
})();

Two consecutive Animation will not run in jQuery

please see this script:
<style type="text/css">
.div1
{
background-color: Aqua;
width: 400px;
height: 30px;
}
.div2
{
background-color: Fuchsia;
width: 400px;
height: 30px;
}
.div3
{
background-color: Green;
width: 400px;
height: 30px;
}
.div4
{
background-color: Orange;
width: 400px;
height: 30px;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
var timer = setInterval(showDiv, 2000);
var counter = 0;
function showDiv() {
if (counter == 0) { counter++; return; }
$('div.My').css('height', '30px');
$('div.My').animate({ height: '30' }, 2000, function () { alert('i'); });
$('div.My')
.stop()
.filter(function () { return this.id.match('div' + counter); })
.animate({ height: '50' }, 500, function () { });
counter == 4 ? counter = 0 : counter++;
}
});
</script>
<body>
<div>
<div class="div1 My" id="div1">
</div>
<div class="div2 My" id="div2">
</div>
<div class="div3 My" id="div3">
</div>
<div class="div4 My" id="div4">
</div>
</div>
</body>
I want every 5 second my div become large and then become normal and next div become large.The problem is first animation does not run and just second animation run.Where is the problem?
JSFiddle Sample
Edit 1)
I want when next div become large previous div become normal concurrently.Not previous become normal and then next become large
Check out my fork of your fiddle and let me know if this is doing what you want. You had a call to .stop() in the middle there, which was blocking the slow shrinking animation from displaying.
Now the full script is:
$(document).ready(function () {
var timer = setInterval(showDiv, 2000);
var counter = 0;
function showDiv() {
if (counter == 0) { counter++; return; }
$('div.My').animate({ height: '30px' }, { duration: 500, queue: false });
$('div.My')
.filter(function () { return this.id.match('div' + counter); })
.animate({ height: '50px' }, { duration: 500, queue: false });
counter == 4 ? counter = 0 : counter++;
}
});
Edit - new Fiddle
I didn't feel right about the above code, and it didn't work as expected in my browser, so I found a different approach that I think works more cleanly. This one uses jQuery's step option. I also use addClass and removeClass as a kind of local storage to remember which div needs to be shrunk on the next animation. You could do some math with counter and get the same result, but this works.
$(document).ready(function () {
var timer = setInterval(showDiv, 2000);
var counter = 0;
function showDiv() {
if (counter == 0) { counter++; return; }
$shrinker = $("div.big").removeClass("big");
$grower = $("#div"+counter);
$grower
.animate({ height:50 },
{duration:500,
step: function(now, fx) {
$shrinker.css("height", 80-now);
}
}
);
$grower.addClass("big");
counter == 4 ? counter = 0 : counter++;
}
});
The step body looks a bit weird, but it guarantees that at each moment of the animation, the total height of the div stack remains constant. Basically, the total height of the shrinking and growing divs (min:30, max:50) has to be 80 at all times, so the height of the shrinking div should be 80 - the height of the growing div.

How to detect that the last or 1st list item is displayed in its container with javascript/jquery

I'm doing a carousel for the 1st time and I'm having difficulties to detect when the last or 1st <li> in the list is displayed in the viewport (its container). I want that when the last item is displayed to either disable the next or previous buttons, or to continue from the 1st or vice-versa (I haven't decided yet on what should happen...). And no plugins please, I'm still in my learning phase...
JSFiddle: http://jsfiddle.net/aayPV/
var slidesList = $('#slides').find('ul'),
slide = $('#slides li');
slidesList.css('width', (slide.length * slide.outerWidth(true)));
$('#ctrls').delegate('a', 'click', function(e) {
var thisElem = $(this),
lastLiPos = slidesList.find('li:last').position(),
lastLiPosLeft = lastLiPos.left,
lastLiPosTop = lastLiPos.top;
e.preventDefault();
if (thisElem.hasClass('next')) {
slidesList.animate({ marginLeft: '-=' + slide.outerWidth(true) + 'px' }, 300);
if ($('#slides li:last').position().left < ((slide.length * slide.outerWidth(true)) - (slide.outerWidth(true) * 5))) {
//Disable nextbutton
}
} else if (thisElem.hasClass('prev')) {
slidesList.animate({ marginLeft: '+=' + slide.outerWidth(true) + 'px' }, 300);
//If 1st item is displayed, disable prev button
}
});
HTML:
<div id="carousel">
<div id="ctrls">
Prev
Next
</div>
<div id="slides">
<ul>
<li><p>1</p></li>
<li><p>2</p></li>
<li><p>3</p></li>
<li><p>4</p></li>
<li><p>5</p></li>
</ul>
</div>
</div>
CSS:
#ctrls {
margin-bottom: 10px;
}
#slides {
width: 305px;
border: 1px solid #555;
overflow: hidden;
}
#slides li {
width: 100px;
height: 100px;
border: 1px solid #999;
background: #e5e5e5;
float: left;
color: #777;
}
#slides li p {
font-family: arial, tahoma;
font-size: 46px;
font-weight: bold;
text-align: center;
margin-top: 25%;
}
Many thanks
I hope below codes will help you,
if (thisElem.hasClass('next')) {
if(lastLiPosLeft >= 2 ) { //I have edited this line changed >=0 to >=2
slidesList.animate({ marginLeft: '-=' + slide.outerWidth(true) + 'px' }, 300);
}
else {
$(".next").css('display', 'none');
}
} else if (thisElem.hasClass('prev')) {
//if( ) //this is for previous button
slidesList.animate({ marginLeft: '+=' + slide.outerWidth(true) + 'px' }, 300);
same condition take for right position and fix for previous button.
I have tested for Next.
NEW UPDATED ANSWER
I've updated your fiddle...
for reference http://jsfiddle.net/aayPV/22/
I think checking on the value of a single variable will be alot more efficient than checking the position of the slide against the length of the total slider...
var slidesList = $('#slides').find('ul'),
slide = $('#slides li');
slidesList.css('width', (slide.length * slide.outerWidth(true)));
var i=0,
last = slide.length - 3;
$('#ctrls').delegate('a', 'click', function(e) {
var thisElem = $(this),
lastLiPos = slidesList.find('li:last').position(),
lastLiPosLeft = lastLiPos.left,
lastLiPosTop = lastLiPos.top;
console.log(lastLiPosLeft, '\n', slidesList.position().left);
e.preventDefault();
if (thisElem.hasClass('next')) {
if(i==last) {
alert('end'); return false;
} else {
++i;
slidesList.animate({ marginLeft: '-=' + slide.outerWidth(true) + 'px' }, 300);
}
} else {
if (thisElem.hasClass('prev')) {
if(i==0) {
alert('beginning'); return false;
} else {
--i;
slidesList.animate({ marginLeft: '+=' + slide.outerWidth(true) + 'px' }, 300);
}
}
}
});
OLD ORIGINAL ANSWER
http://jsfiddle.net/YmjF7/31/
var items = $('li');
var i = 0,
last = items.length -1;
$('#next').click(function(){
//increment i until it reaches the end of the array
if(i == last) {alert('end'); return false;} else {
i++;
i = i % items.length;
alert('Item '+ (i+1));
}
});
$('#prev').click(function(){
//decrease i until it reaches the beginning of the array
if(i == 0) {alert('beginning'); return false;} else {
--i;
i = i % items.length;
alert('Item '+ (i+1));
}
});
I give some credit to the following questions/answers:
Increase and decrease a variable until a number is reached in javascript
jQuery append different text each click

Categories