Extend timeout function when button is clicked - javascript

This piece of code works, but I am trying to get the timeout function to reset to '0' every time the button is clicked.
var running = false,
count = 0,
run_for = 700;
var end_counter = function() {
if (running) {
running = false;
$("#status").text("Not Running");
alert(count);
started_at = 0;
}
};
$('button').click(function() {
if (running) {
count++;
} else {
running = true;
$("#status").text("Running");
count = 1;
setTimeout(end_counter, run_for);
}
});

Just cancel and restart it:
var timerId,
count = 0;
function end_counter() {
$("#status").text("Not Running");
alert(count);
count = 0;
}
$('button').click(function() {
$("#status").text("Running");
count++;
clearTimeout(timerId);
timerId = setTimeout(end_counter, 700);
});

var running = false,
count = 0,
run_for = 700;
var timer;
var end_counter = function() {
if (running) {
running = false;
$("#status").text("Not Running");
alert(count);
started_at = 0;
}
};
$('button').click(function() {
clearTimeout(timer);
if (running) {
count++;
timer = setTimeout(end_counter, run_for);
} else {
running = true;
$("#status").text("Running");
count = 1;
timer = setTimeout(end_counter, run_for);
}
});
Set timer to a variable - then clear it on click and restart it after count.

Related

Play an audio file in Javascript

I'm trying to play an audio file in js. what am i doing wrong?
The script auto-stops after some events which is working 100%, now all I want to do is add a sound after it stops
Here is the code in:
function stop() {
stop_flag = true;
var audio = new Audio('play.mp3');
audio.play();
}
Here is the complete script.js the function is at the bottom.
chrome.runtime.onMessage.addListener(function(message) {
if (message.action == "init") {
init(message.options.divider, message.options.delay, message.options.maxLosses);
}
if (message.action == "stop") {
stop();
}
});
var stop_flag;
function init(divider, delay, maxLosses) {
var $table = $('table.dice_table').last();
var lastBetNumber;
var lastBetValue;
var lastProfit;
var losses = 0;
stop_flag = false;
loop_start();
function loop_start() {
lastBetNumber = getLastBetNumber();
var betValue = (getCurrentBalance() / divider).toFixed(9);
//var betValue = (getCurrentBalance() / divider);
lastBetValue = betValue;
$("input.bet").val(betValue);
play();
setTimeout(loop, delay);
}
function loop() {
if (stop_flag)
return;
waitForTableChange()
.then(roll)
.catch(loop_start);
function roll() {
//only if the last bet has changed \/
lastBetNumber = getLastBetNumber();
lastProfit = $table.children('tbody').children('tr').first().children('td').last().text()[0];
changeBet();
if (losses >= maxLosses)
return;
play();
setTimeout(loop, delay);
}
}
function waitForTableChange() {
return new Promise(function(resolve, reject) {
var n = 0;
attempt();
function attempt() {
n++;
if (n >= 100) {
reject();
return;
}
if (getLastBetNumber() == lastBetNumber) {
setTimeout(attempt, 100);
return;
}
resolve();
}
});
}
function changeBet() {
var newBetValue;
if (lastProfit == "-") {
losses++;
newBetValue = lastBetValue * 2;
} else {
losses = 0;
newBetValue = (getCurrentBalance() / divider).toFixed(9);
}
lastBetValue = newBetValue;
$("input.bet").val(newBetValue);
}
function play() {
$('input.clDicePlay').first()[0].click();
}
function getLastBetNumber() {
return $table.children('tbody').children('tr').first().children('td').first().text();
}
function getCurrentBalance() {
return $('.dice_select .chosen-single span').text().split('- ')[1].split(' ')[0];
}
}
function stop() {
var audio = new Audio('play.mp3');
stop_flag = true;
audio.play();
}
The problem is you are setting audio within the function stop(), which makes it local to that function. Once a function has been executed, all local vars are destroyed. You need to use the global scope to keep the object alive.
For example:
// set 'audio' in the global scope
var audio = new Audio('/path/to/default.mp3');
// create a play / pause button
function playPause(e) {
// NOTE: audio is from the gloabl scope
if (this.textContent == 'Play') {
audio.play();
this.textContent = 'Pause';
} else {
audio.pause();
this.textContent = 'Play';
}
}
window.onload = function() {
var a = document.getElementById('func');
a.addEventListener('click',playPause,false);
}
<button id="func">Play</button>

Check if time since last click is greater than 2 seconds

If found how to do this thanks to this post, but as you can see by the code bellow I'm trying to console.log('Done'); when the time since the last click is greater than 2 seconds. However this doesn't work.
var lastClick = 0;
var button_pressed = false;
let button1 = document.getElementById('button1');
let button2 = document.getElementById('button2');
button1.onclick = function() {
button_pressed = true;
CheckAnswer();
}
button2.onclick = function() {
button_pressed = true;
CheckAnswer();
}
function CheckAnswer() {
if(button_pressed === true) {
var d = new Date();
var t = d.getTime();
if(t - lastClick < 2000) {
console.log('Continue');
}
} else if (t - lastClick > 2000) {
console.log('Done');
}
lastClick = t;
}
<button id="button1">Button1</button>
<button id="button2">Button2</button>
Thank you for your help.
The code never reaches the else if, because it requires button_pressed to be false
I fixed your code, see below.
The else if is now declared withtin the button_pressed === true statement.
function CheckAnswer() {
if(button_pressed === true) {
var d = new Date();
var t = d.getTime();
if(t - lastClick < 2000) {
console.log('Continue');
} else {
console.log('Done');
}
}
lastClick = t;
}
var lastClick = Date.now();
var button_pressed = false;
let button1 = document.getElementById('button1');
let button2 = document.getElementById('button2');
button1.onclick = function() {
button_pressed = true;
CheckAnswer();
}
button2.onclick = function() {
button_pressed = true;
CheckAnswer();
}
function CheckAnswer() {
var t = Date.now();
var diff = t - lastClick;
if(diff < 2000) {
console.log('Continue');
} else {
console.log('Done');
}
lastClick = t;
}
<button id="button1">Button1</button>
<button id="button2">Button2</button>

How to make annyang detect no sound for 3 seconds or longer, then start next audio?

I got a person's help to build this so far. But my goal is after the first audio file, the program would still listen what the user says until the user finishes talking. And then if the program doesn't detect anything for 3 seconds(or longer), it will play the next audio. This program will do this over and over until all audio files have played.
However, there's one more case. If the user is a 2 years old kid, which means the kid might need to spend 2 seconds or longer between 2 sentences. In this case, the annyang might think the user has finished their sentences and play next audio. This way the program would interrupt the user speech. How should I handle this?
That person who gave me ideas of using setInverval and create some date objects and then minus date objects to get a time greater than 3 seconds, and play next audio. But it's not working. Is my logic of code wrong or there's a better way?
Any help I would appreciate it. Thank you in advance.
<script>
audio = new Audio();
if (annyang)
{
annyang.addCallback('start', function() {console.log('started listening!');});
annyang.addCallback('soundstart', function(){onSoundDetected();});
function monitorSound()
{
if(monitorId && monitorId > 0) return;
var monitorId = window.setInterval(function(){trackSound() }, 1000);
}
var lastSound= new Date();
function trackSound()
{
var now = new Date();
if ((now - lastSound) > 3000)
{
playNextAudio();
return;
}
}
function stopListening()
{
var monitorId = 0;
window.clearInterval(monitorId);
annyang.removeCallback('soundstart', onSoundHeard);
annyang.addCallback('result', function() {playNextAudio(); });
}
function onSoundHeard()
{
lastSound = new Date();
console.log(lastSound);
}
function playNextAudio()
{
if(audioIndex === playList.length - 1)
{
console.log("Played all audios");
return; // we have played all audio
}
else
{
annyang.addCallback('result', function() {
audio.src = dir + playList[audioIndex++] + extention;
audio.load();
//audio.ended = audio.play();
//audio.ended = setTimeout(function(){audio.play();}, 1500);
setTimeout(function(){audio.play();}, 1000);
});
}
}
function playFirstAudio()
{
audio.src = dir + playList[audioIndex] + extention;
audio.load();
audio.ended = setTimeout(function(){audio.play();}, 1000);
console.log('First audio is playing');
}
function onSoundDetected()
{
console.log('sound was detected');
playFirstAudio();
monitorSound();
}
// Start from here
var playList = ["1_hello", "2_how_old", "3_what_did_you_make"];
var dir = "sound/";
var extention = ".wav";
var audioIndex = 0;
annyang.debug(true);
};
</script>
You have logic errors in your code. When stopping and starting timers, you need to refer to the global variables.
This code isn't going to stop your timer:
function stopListening()
{
var monitorId = 0;
window.clearInterval(monitorId);
}
Your code also only initiates your play loop. It never starts the listening timer.
You logic will also play the first song twice.
To demonstrate the control flow, I have mocked the audio and annyang objects. The audio mock simulates the playing of 3 ten second audio files. When the window loads, the first audio mock will play. After which the annyang and the listening timer will start.
To mock annyang's sound detect there is a "mock sound" button. If it is clicked it will extend sound detection for another 3 seconds. Once 3 seconds goes by annyang will be paused and the next audio is played.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Annyang Mock</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var AudioMock = function () {
this.src = null;
this.start = null;
this.timer = 0;
var that = this;
this.load = function () {
$('#AudioState').html("Loaded " + that.src);
}
this.play = function () {
that.start = new Date();
$('#AudioState').html("Playing: " + this.src);
window.setTimeout(that.end, 10000);
that.timer = window.setInterval(that.mockPlayTime, 500);
}
this.mockPlayTime = function () {
var d = new Date();
var elapsed = (d - that.start) / 1000;
$('#AudioState').html("Playing: " + that.src + " " + elapsed + " secs");
}
this.endMockPlayTime = function () {
window.clearInterval(that.timer);
}
this.end = function () {
that.endMockPlayTime();
$('#AudioState').html("Ended: " + that.src);
if (that.ended) {
that.ended();
}
}
this.ended = null;
};
var annyangMock = function () {
this.callbacks = {};
this.paused = false;
};
annyangMock.prototype.addCallback = function (name, callback) {
this.callbacks[name] = callback;
}
annyangMock.prototype.removeCallback = function (name, callback) {
this.callbacks[name] = null;
}
annyangMock.prototype.pause = function () {
$('#AnnyangState').html("Annyang: pause()");
this.paused = true;
}
annyangMock.prototype.start = function () {
$('#AnnyangState').html("Annyang: start()");
this.paused = false;
}
annyangMock.prototype.invoke = function (name) {
if (!this.paused) {
$('#AnnyangState').html("called(" + name + ")");
var cb = this.callbacks[name];
if (cb) cb();
}
}
annyangMock.prototype.debug = function (flag) { };
var annyang = new annyangMock();
var annyangMock = function () {
var callbacks = {};
var _paused = false;
var pause = function () {
$('#AnnyangState').html("Annyang: pause()");
_paused = true;
}
function addCallback(name, callback) {
callbacks[name] = callback;
}
function removeCallback(name, callback) {
callbacks[name] = null;
}
function invoke(name) {
$('#AnnyangState').html("called(" + name + ")");
if (name == "start") {
_paused = false;
}
else {
if (!_paused) {
var cb = callbacks[name];
if (cb) cb();
}
}
}
}
</script>
<script>
audio = new AudioMock();
var monitorId = 0;
if (annyang) {
annyang.addCallback('start', function () { console.log('started listening!'); });
annyang.addCallback('soundstart', onSoundHeard);
function monitorSound() {
lastSound = new Date();
if (monitorId && monitorId > 0) return;
monitorId = window.setInterval(trackSound, 1000);
annyang.start();
}
var lastSound = new Date();
function onSoundHeard() {
lastSound = new Date();
//console.log(lastSound);
}
function trackSound() {
var now = new Date();
var elapsed = now - lastSound;
$('#AnnyangState').html("Listening: " + (elapsed / 1000) + " secs");
if ((now - lastSound) > 3000) {
stopListening();
playNextAudio();
return;
}
}
function stopListening() {
window.clearInterval(monitorId);
monitorId = 0;
annyang.pause();
}
function playNextAudio() {
if (audioIndex === playList.length - 1) {
console.log("Played all audios");
return; // we have played all audio
}
else {
audio.src = dir + playList[++audioIndex] + extention;
load();
setTimeout(function () { play(); }, 1000);
}
}
function load() {
$($('#playlist li')[audioIndex]).addClass("loading");
audio.load();
}
function play() {
audio.play();
$('#playlist li').removeClass("loading")
var li = $('#playlist li')[audioIndex];
$(li).addClass("playing");
}
function playFirstAudio() {
annyang.pause();
audio.src = dir + playList[audioIndex] + extention;
load();
audio.ended = function () {
$('#playlist li').removeClass("playing");
lastSound = new Date(); // set timestamp
monitorSound(); // poll sound detection
}
setTimeout(function () { play(); }, 1000);
//console.log('First audio is playing');
}
// Start from here
var playList = ["1_hello", "2_how_old", "3_what_did_you_make"];
var dir = "sound/";
var extention = ".wav";
var audioIndex = 0;
annyang.debug(true);
$(document).ready(function () {
playFirstAudio();
var l = $("<ol>");
playList.forEach(function (j) {
l.append($("<li>").html(j));
});
$('#playlist').append(l);
})
};
</script>
<style type="text/css">
#playlist li {
width: 200px;
padding: 5px;
}
div {
padding: 15px;
}
#playlist li.playing {
border: 1px solid green;
background: #dedede;
}
#playlist li.loading {
border: 1px solid red;
background: #dedede;
}
</style>
</head>
<body>
<div>
<b>Annyang State:</b> <span id="AnnyangState"></span>
</div>
<div><b>Audio State:</b> <span id="AudioState"></span></div>
<div id="playlist">
<b>Playlist:</b>
</div>
<div id="Controls">
<input id="MockSound" type="button" value="Mock Sound" onclick="annyang.invoke('soundstart');" />
</div>
</body>
</html>

How to pause a setTimeout function

I have this code to start a setTimeout function with a button and to stop it with another button, but if I stop it and start it, it will start over, Is there any way to get a pause/continue button?
Javascript code:
var timeout1, timeout2, timeout3;
function timedText() {
timeout1 = setTimeout(desertAK, 1000)
timeout2 = setTimeout(fourAlarmShotgun, 5000)
timeout3 = setTimeout(frostbiteAR, 9000)
}
function stopTimeout() {
clearTimeout(timeout1);
clearTimeout(timeout2);
clearTimeout(timeout3);
}
function desertAK() {
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Desert%20Warfare%20AK-47%22"></iframe>';
}
function fourAlarmShotgun() {
document.getElementById("leser2").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Four%20Alarm%2012GA%20Pump%20Shotgun%22"></iframe>';
}
function frostbiteAR() {
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Frostbite%20AR-15%22"></iframe>';
}
HTML buttons:
<button onclick="timedText()">Start</button>
<button onclick="stopTimeout()">Stop</button>
var Timer = (function () {
var isExeced = [1,1,1];
var timeout1, timeout2, timeout3;
var startTime, costTime = 0;
var finished = false;
var status = 0;
function reset () {
costTime = 0;
status = 0;
finished = false;
isExeced = [1,1,1];
}
function desertAK () {
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Desert%20Warfare%20AK-47%22"></iframe>';
}
function fourAlarmShotgun () {
document.getElementById("leser2").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Four%20Alarm%2012GA%20Pump%20Shotgun%22"></iframe>';
}
function frostbiteAR () {
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Frostbite%20AR-15%22"></iframe>';
}
function timedText () {
if (finished) {
return resume();
}
if (status === 1) {
return;
} else {
status = 1;
}
startTime = +new Date();
if (isExeced[0]) {
timeout1 = setTimeout(function () {
isExeced[0] = 0;
desertAK();
}, 1000 - costTime);
}
if (isExeced[1]) {
timeout2 = setTimeout(function () {
isExeced[1] = 0;
fourAlarmShotgun();
}, 5000 - costTime);
}
if (isExeced[2]) {
timeout3 = setTimeout(function () {
isExeced[2] = 0;
finished = true;
status = 0;
frostbiteAR();
}, 9000 - costTime);
}
}
function stopTimeout () {
costTime += +new Date() - startTime;
status = 0;
clearTimeout(timeout1);
clearTimeout(timeout2);
clearTimeout(timeout3);
}
function resume () {
stopTimeout();
reset();
timedText();
}
return {
start: timedText,
stop: stopTimeout,
resume: resume
}
})();
Use like below:
<button onclick="Timer.start();">Start</button>
<button onclick="Timer.stop();">Stop</button>
Add breakpoint variable status which save last doing operation
var timeout1, timeout2, timeout3;
var status = 0;
function timedText() {
if(status + 1 == 1) {
timeout1 = setTimeout(desertAK, 1000)
timeout2 = setTimeout(fourAlarmShotgun, 5000)
timeout3 = setTimeout(frostbiteAR, 9000)
} else if(status == 2) {
timeout2 = setTimeout(fourAlarmShotgun, 5000)
timeout3 = setTimeout(frostbiteAR, 9000)
timeout1 = setTimeout(desertAK, 1000)
} else {
timeout3 = setTimeout(frostbiteAR, 9000)
timeout1 = setTimeout(desertAK, 1000)
timeout2 = setTimeout(fourAlarmShotgun, 5000)
}
}
function stopTimeout() {
clearTimeout(timeout1);
clearTimeout(timeout2);
clearTimeout(timeout3);
}
function desertAK() {
status = 0;
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Desert%20Warfare%20AK-47%22"></iframe>';
}
function fourAlarmShotgun() {
status = 1;
document.getElementById("leser2").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Four%20Alarm%2012GA%20Pump%20Shotgun%22"></iframe>';
}
function frostbiteAR() {
status = 2;
document.getElementById("leser").innerHTML = '<iframe src="https://opskins.com/?loc=shop_search&sort=lh&app=433850_1&search_item=%22Frostbite%20AR-15%22"></iframe>';
}

Run jQuery after setInterval function is complete

I have a basic count function and i wish to run some code only after the count function is complete. Is there a way of doing this simply?
DEMO http://jsfiddle.net/vyN6V/243/
Current Code
var number = 1500;
var aValue = 300;
function count(Item) {
var current = aValue;
Item.val(aValue += 1);
if (current < number) {
setTimeout(function () {
count(Item)
}, 0.1);
}
}
count($(".input"));
// code here should only run when count function is complete
I tried this, to no avail
var number = 1500;
var aValue = 300;
function count(Item) {
var current = aValue;
Item.val(aValue += 1);
if (current < number) {
setTimeout(function () {
count(Item)
}, 0.1);
}
}
count(function$(".input"){
// code here should only run when count function is complete
});
FIDDLE
var number = 1500;
var aValue = 300;
function count(Item) {
var current = aValue;
Item.val(aValue += 1);
if (current < number) {
setTimeout(function () {
count(Item)
}, 0.1);
} else {
$('span').text('code here should only run when function count is complete');
}
}
count($(".input"));

Categories