setTimeout sequence is bypassing a previous setInterval basically nullifying the setInterval event - javascript

I am creating a slot machine which has a re-spin feature (which is identified as stampede in the code) on random wins like the machine Haywire in the casinos.
The initial spin/win works fine... after a random re-spin(s) is generated script then randomly selects the number of re-spins awarded and calls stampede() which loops through the number of spins awarded.
stampede() itself is in a 'setTimeout()' which will delay its start if a big win is hit on the initial win for a congrats screen to run... this works fine.
The reel annimation on the spin is handled by setInterval() for each reel. The problem is that this code is being bypassed by the stop reel code which is in a set of setTimeOut()functions used to stop the reels. It goes directly to the stop reel.
The loop itself works fine in regards to sliding the stampede announcement screen in and out and adjusting the "show win and bank add on screen" with the exception of the .animateNumber() not working inside of the stampede().
Both the code to animate the reels and stop them work fine outside of the stampede() but as stated the reel animation does not work in stampede()...
Here is my Code:
// check for respin
var respinCount = 0;
var respinCheck = randItem(1, 1000);
if((+respinCheck) <= 899){respinCount = 0}
else if((+respinCheck) >= 900 && (+respinCheck) <= 950){respinCount = 1;}
else if((+respinCheck) >= 951 && (+respinCheck) <= 970){respinCount = 2;}
else if((+respinCheck) >= 971 && (+respinCheck) <= 980){respinCount = 3;}
else if((+respinCheck) >= 981 && (+respinCheck) <= 990){respinCount = 4;}
else if((+respinCheck) >= 991 && (+respinCheck) <= 999){respinCount = 5;}
else if((+respinCheck) == 1000){respinCount = 10;}
// adjust stampede delay if win is >= 100
if(win >= 100){var stampede_delay = 7000;}else if (win <= 99){var stampede_delay = 10;}
setTimeout(function() {// stampede delay
if(respinCount == 0){respinCount = 3;} // for testing stampede
if(respinCount >= 1){
// turn off auto spin if active
if(auto_set == 1){ auto_set = 0; $("#autoData").val(auto_set);
if($("#auto_spin").hasClass("active")){$("#auto_spin").removeClass("active");}}
// stampede()
(function stampede(i) {
setTimeout(function () {
// announce stampede
$("#stampede_wrap").slideDown().delay(700).slideUp();
// make reel stop transparent
$("#reel_1").html('<img src="images/stop-images/transparent.png">');
$("#reel_2").html('<img src="images/stop-images/transparent.png">');
$("#reel_3").html('<img src="images/stop-images/transparent.png">');
// add reel sprite class to reels
if (!$('#reel_1').hasClass("reel-1-sprite")){$('#reel_1').addClass('reel-1-sprite')};
if (!$('#reel_2').hasClass("reel-2-sprite")){$('#reel_2').addClass('reel-2-sprite')};
if (!$('#reel_3').hasClass("reel-3-sprite")){$('#reel_3').addClass('reel-3-sprite')};
// annimate reels
var x = 0; var xx = 0; var xxx = 0; // reel increment variables
var r1a = setInterval(function(){ // annimate/stop reel_1
if(ar.length == x){x = 0;}
else {$('.reel-1-sprite').css("background-position", aru[x]); x++;}
},0);
var r2a = setInterval(function(){ // annimate/stop reel_2
if(ar.length == xx){xx = 0;}
else {$('.reel-2-sprite').css("background-position", ar[xx]); xx++;}
},0);
var r3a = setInterval(function(){ // annimate/stop reel_3
if(ar.length == xxx){xxx = 0;}
else {$('.reel-3-sprite').css("background-position", aru[xxx]); xxx++;}
},0);
// stop reels
setTimeout(function() { // stop reel_1
$("#reel_1").removeClass("reel-1-sprite");
$("#reel_1").html('<img src="images/stop-images/'+rn1sc+'.png">');
}, 800);
setTimeout(function() { // stop reel_2
$("#reel_2").removeClass("reel-2-sprite");
$("#reel_2").html('<img src="images/stop-images/'+rn2sc+'.png">');
}, 1000);
setTimeout(function() { // stop reel_3
$("#reel_3").removeClass("reel-3-sprite");
$("#reel_3").html('<img src="images/stop-images/'+rn3sc+'.png">');
}, 1200);
// adjust bank for this stampede spin
pBank = ((+bank) + (+win_value)); updateBank(uid,pBank); bank = (+pBank);
$("#creditData,#bankData").val((+bank)); $("#winData").val((+win_value));
// show win and bank add on screen
var comma_separator = $.animateNumber.numberStepFactories.separator(',');
$('#thisWin').animateNumber({ number: win_value, numberStep: comma_separator },500);
$('#credit_count_text').prop('number', (+now)).animateNumber({ number:(+bank), numberStep:comma_separator},500);
$("#creditData").val((+bank));
if (--i) stampede(i);
}, 2000)
})(respinCount); // end stampede
}; // end if(respinCount >= 1)
}, stampede_delay); // end stampede delay
I am at a loss... any assistance would be greatly appreciated.
Thanks in advance Pete

Related

play sound when counter hits 0 within an event listener

I decided to post a new question again because my previous one was a bit convoluted.
so i have this timer on a loop.
let cc = 3;
(function count(cc) {
document.getElementById("cco").innerHTML = cc;
if (cc > 0)
setTimeout(function() { count(--cc); }, 1000);
if(cc ==0)
setTimeout(function() {
cc = 4
count(--cc); }, 1000);
})(3);
and i have this event listener for several audio buttons that may play at the same time.
parent.addEventListener('click',player2, false)
function player2(e){
if(e.target !== e.currentTarget){
let clickedSound = e.target.id
if (soundOb[clickedSound].duration > 0 && soundOb[clickedSound].paused) {
let counter = document.getElementById('cco').innerHTML;
//only play any sound when the timer (cc = 0) hits 0
soundOb[clickedSound].play()
soundOb[clickedSound].loop = true;
} else {
soundOb[clickedSound].pause();
soundOb[clickedSound].currentTime = 0;
}
}
}
i need the sound to play only when the counter hits 0. for tempo/beet reasons.
i can only rely on an external counter cus not all audio files have the same length.
thank you

Creating a simple "smooth scroll" (with javascript vanilla)

I have been trying to make a simple "smoothscroll" function using location.href that triggers on the mousewheel. The main problem is that the EventListener(wheel..) gets a bunch of inputs over the span of ca. 0,9 seconds which keeps triggering the function. "I only want the function to run once".
In the code below I have tried to remove the eventlistener as soon as the function runs, which actually kinda work, the problem is that I want it to be added again, hence the timed function at the bottom. This also kinda work but I dont want to wait a full second to be able to scroll and if I set it to anything lover the function will run multiple times.
I've also tried doing it with conditions "the commented out true or false variables" which works perfectly aslong as you are only scrolling up and down but you cant scroll twice or down twice.
window.addEventListener('wheel', scrolltest, true);
function scrolltest(event) {
window.removeEventListener('wheel', scrolltest, true);
i = event.deltaY;
console.log(i);
if (webstate == 0) {
if (i < 0 && !upexecuted) {
// upexecuted = true;
location.href = "#forside";
// downexecuted = false;
} else if (i > 0 && !downexecuted) {
// downexecuted = true;
location.href = "#underside";
// upexecuted = false;
}
}
setTimeout(function(){ window.addEventListener('wheel', scrolltest, true); }, 1000);
}
I had hoped there was a way to stop the wheel from constantly produce inputs over atleast 0.9 seconds.
"note: don't know if it can help in some way but when the browser is not clicked (the active window) the wheel will registre only one value a nice 100 for down and -100 for up"
What you're trying to do is called "debouncing" or "throttling". (Those aren't exactly the same thing, but you can look up the difference in case it's going to matter to you.) Functions for this are built into libraries like lodash, but if using a library like that is too non-vanilla for what you have in mind, you can always define your own debounce function: https://www.geeksforgeeks.org/debouncing-in-javascript/
You might also want to look into requestanimationframe.
a different approach
okey after fiddeling with this for just about 2 days i got fustrated and started over. no matter what i did the browsers integrated "glide-scroll" was messing up the event trigger. anyway i decided to animate the scrolling myself and honestly it works better than i had imagined: here is my code if anyone want to do this:
var body = document.getElementsByTagName("BODY")[0];
var p1 = document.getElementById('page1');
var p2 = document.getElementById('page2');
var p3 = document.getElementById('page3');
var p4 = document.getElementById('page4');
var p5 = document.getElementById('page5');
var whatpage = 1;
var snap = 50;
var i = 0;
// this part is really just to read what "page" you are on if you update the site. if you add more pages you should remember to add it here too.
window.onload = setcurrentpage;
function setcurrentpage() {
if (window.pageYOffset == p1.offsetTop) {
whatpage = 1;
} else if (window.pageYOffset == p2.offsetTop) {
whatpage = 2;
} else if (window.pageYOffset == p3.offsetTop) {
whatpage = 3;
} else if (window.pageYOffset == p4.offsetTop) {
whatpage = 4;
} else if (window.pageYOffset == p5.offsetTop) {
whatpage = 5;
}
}
// this code is designet to automaticly work with any "id" you have aslong as you give it a variable called p"number" fx p10 as seen above.
function smoothscroll() {
var whatpagenext = whatpage+1;
var whatpageprev = whatpage-1;
var currentpage = window['p'+whatpage];
var nextpage = window['p'+whatpagenext];
var prevpage = window['p'+whatpageprev];
console.log(currentpage);
if (window.pageYOffset > currentpage.offsetTop + snap && window.pageYOffset < nextpage.offsetTop - snap){
body.style.overflowY = "hidden";
i++
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset <= nextpage.offsetTop + snap && window.pageYOffset >= nextpage.offsetTop - snap) {
i=0;
window.scrollTo(0, nextpage.offsetTop);
whatpage += 1;
body.style.overflowY = "initial";
}
} else if (window.pageYOffset < currentpage.offsetTop - snap && window.pageYOffset > prevpage.offsetTop + snap){
body.style.overflowY = "hidden";
i--
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset >= prevpage.offsetTop - snap && window.pageYOffset <= prevpage.offsetTop + snap) {
i=0;
window.scrollTo(0, prevpage.offsetTop);
whatpage -= 1;
body.style.overflowY = "initial";
}
}
}
to remove the scrollbar completely just add this to your stylesheet:
::-webkit-scrollbar {
width: 0px;
background: transparent;
}

.ScrollLeft in Firefox issue

I have this script:
<script>
Array.prototype.forEach.call(document.querySelectorAll(".thumbs div"), function ($div) {
$div.style.width = document.querySelectorAll(" img").length * 100 / 4 + "px";
});
document.querySelector("#next").onclick = function () {
var i = 100;
var intervalId = setInterval(function () {
document.querySelector(".thumbs").scrollLeft += 1;
if (i == 0) {
clearInterval(intervalId);
}
i--;
});
};
document.querySelector("#prev").onclick = function () {
var i = 100;
var intervalId = setInterval(function () {
document.querySelector(".thumbs").scrollLeft -= 1;
if (i == 0) {
clearInterval(intervalId);
}
i--;
});
};
</script>
That scrolls the slider thumbs when clicking the next or prev buttons. In Opera and Chrome, it works fine - with one click to the button, .thumbs scrolls 100px. But in Firefox, with one click, it scrolls 1px.
What can I do to fix that?
That's because you aren't passing an interval delay to setInterval, and so Firefox only runs it once. Other browsers seem to take it as if you were passing it 0 (the minimum delay).
Just pass 0 or any value you like, to both of your intervals.
http://jsfiddle.net/ar8au1o6/1/
var intervalId = setInterval(function () {
document.querySelector(".thumbs").scrollLeft += 1;
if (i == 0) {
clearInterval(intervalId);
}
i--;
}, 0); // <-- Set each interval in your code to 0,
// Or any other delay.
// If you set it to 0, the browser will pick the minimum delay.

make a character jump inside canvas

this is my jsfiddle : http://jsfiddle.net/2tLCk/4/
as you can see if you hit the up button Mario will jump far to the up and go back down once but if u hit it again he will not jump how can i fix this problem ? when I hit the up button Mario will jump to a specific location let's say y=32 and than go back down (always not just for one time ) ?
var Jump = function () {
if (character.y > limit && !goingDown) {
character.y -= limit;
} else {
goingDown = true;
character.y += limit;
if (character.y >= 184) {
clearInterval(jumping);
goingDown = false;
limit = 0;
character.y = 184;
}
}
}
Set the limit inside this if statement
if (keydown.up) {
limit = 10;
jumping = setInterval(Jump, 150);
}
DEMO
To specify a specific height you can delcare a new variable called limitHeight and switch it with limit in this if statement
if (character.y > limitHeight && !goingDown) {
// ^^^^^^^^^^^
in this new demo i also put clearInterval in the keydown.up statement to fix some bugs
DEMO
You set your limit to 0 when the jump is done. So there is 0 substracted from the y position on the second jump. In your initialization you set limit to 10. If I set limit to 10 after jump it works again.
fiddle
Relevant code:
var Jump = function () {
if (character.y > limit && !goingDown) {
character.y -= limit;
} else {
goingDown = true;
character.y += limit;
if (character.y >= 184) {
clearInterval(jumping);
goingDown = false;
limit = 10;
character.y = 184;
}
}
}

how to make hide/show text javascript smoother?

I am using this script to hide and show text however, I want to make the transition smoother but I am not sure how to. Here's a demo of it: http://jsfiddle.net/LnE5U/.
Please help me change it to make it smoother.
hide/show text
<div id="showOrHideDiv" style="display: none">hidden text</div>
<script language="javascript">
function showOrHide()
{
var div = document.getElementById("showOrHideDiv");
if (div.style.display == "block")
{
div.style.display = "none";
}
else
{
div.style.display = "block";
}
}
</script>
Here is an example using jQuery's fadeToggle (a shortcut for a more complicated animate)
// assuming jQuery
$(function () { // on document ready
var div = $('#showOrHideDiv'); // cache <div>
$('#action').click(function () { // on click on the `<a>`
div.fadeToggle(1000); // toggle div visibility over 1 second
});
});
HTML
<a id="action" href="#">hide/show text</a>
<div id="showOrHideDiv" style="display: none;">hidden text</div>
DEMO
An example of a pure JavaScript fader. It looks complicated because I wrote it to support changing direction and duration mid-fade. I'm sure there are still improvements that could be made to it, though.
function generateFader(elem) {
var t = null, goal, current = 0, inProgress = 0;
if (!elem || elem.nodeType !== 1) throw new TypeError('Expecting input of Element');
function visible(e) {
var s = window.getComputedStyle(e);
return +!(s.display === 'none' || s.opacity === '0');
}
function fader(duration) {
var step, aStep, fn, thisID = ++current, vis = visible(elem);
window.clearTimeout(t);
if (inProgress) goal = 1 - goal; // reverse direction if there is one running
else goal = 1 - vis; // else decide direction
if (goal) { // make sure visibility settings correct if hidden
if (!vis) elem.style.opacity = '0';
elem.style.display = 'block';
}
step = goal - +window.getComputedStyle(elem).opacity;
step = 20 * step / duration; // calculate how much to change by every 20ms
if (step >= 0) { // prevent rounding issues
if (step < 0.0001) step = 0.0001;
} else if (step > -0.0001) step = -0.0001;
aStep = Math.abs(step); // cache
fn = function () {
// console.log(step, goal, thisID, current); // debug here
var o = +window.getComputedStyle(elem).opacity;
if (thisID !== current) return;
if (Math.abs(goal - o) < aStep) { // finished
elem.style.opacity = goal;
if (!goal) elem.style.display = 'none';
inProgress = 0;
return;
}
elem.style.opacity = (o + step).toFixed(5);
t = window.setTimeout(fn, 20);
}
inProgress = 1; // mark started
fn(); // start
}
return fader;
}
And using it
window.addEventListener( // this section matches the code above
'load',
function () {
var fader = generateFader(document.getElementById('showOrHideDiv'));
document.getElementById('action').addEventListener(
'click',
function () {
fader(1000);
}
);
}
);
DEMO of this
This is quite simple. I have just made a demo and i used setInterval
Here's how it works
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
}
}, 50);
};
JSFiddle Demo Link
Steps
Create a function that accepts a DOM element
Set the opacity of the element to 1
Create a function that loops every 50ms
If the opacity is greater than 0 -> continue
Take away 0.01 from the opacity
if it's less than 0 the animation is complete and hide it completely
Note this is a really simple example and will need a bit of work
You can use somthing like this
$('.showOrHideDiv').toggle(function() {
$('showOrHideDiv').fadeIn('slow', function() {
//fadeIn or fadeOut, slow or fast, all the stuffs you want to trigger, "a function to execute every odd time the element is clicked," says the [jquery doc][1]
});
}, function() {
//here comes "additional handlers to cycle through after clicks," says the [jquery doc][1]
});
I used OPACITY to make it show/hide. See this Example, Full code (without jQuery):
Click here
<div id="MyMesage" style="display:none; background-color:pink; margin:0 0 0 100px;width:200px;">
blablabla
</div>
<script>
function ShowDiv(name){
//duration of transition (1000 miliseconds equals 1 second)
var duration = 1000;
// how many times should it should be changed in delay duration
var AmountOfActions=100;
var diiv= document.getElementById(name);
diiv.style.opacity = '0'; diiv.style.display = 'block'; var counte=0;
setInterval(function(){counte ++;
if ( counte<AmountOfActions) { diiv.style.opacity = counte/AmountOfActions;}
},
duration / AmountOfActions);
}
</script>
I followed iConnor solution and works fine but it had a small issue setInterval will not stop after the element be hidden I added stop interval to make it better performance
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
let hidden_process = window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
console.log('1');
clearInterval(hidden_process);
}
}, 50);
};

Categories

Resources