I found a custom html5 audio player and successfully redesigned it, now I want to add a "loading/buffering" text while player is loading audio (otherwise users may freak out because nothing happening after they hit play).
Here is the code to explain:
function calculateTotalValue(length) {
var minutes = Math.floor(length / 60),
seconds_int = length - minutes * 60,
seconds_str = seconds_int.toString(),
seconds = seconds_str.substr(0, 2),
time = minutes + ':' + seconds
return time;
}
function calculateCurrentValue(currentTime) {
var current_hour = parseInt(currentTime / 3600) % 24,
current_minute = parseInt(currentTime / 60) % 60,
current_seconds_long = currentTime % 60,
current_seconds = current_seconds_long.toFixed(),
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);
return current_time;
}
function initProgressBar() {
var player = document.getElementById('player');
var length = player.duration
var current_time = player.currentTime;
// calculate total length of value
var totalLength = calculateTotalValue(length)
jQuery(".end-time").html(totalLength);
// calculate current value time
var currentTime = calculateCurrentValue(current_time);
jQuery(".start-time").html(currentTime);
var progressbar = document.getElementById('seekObj');
progressbar.value = (player.currentTime / player.duration);
progressbar.addEventListener("click", seek);
if (player.currentTime == player.duration) {
$('#play-btn').removeClass('pause');
}
function seek(evt) {
var percent = evt.offsetX / this.offsetWidth;
player.currentTime = percent * player.duration;
progressbar.value = percent / 100;
}
};
function initPlayers(num) {
// pass num in if there are multiple audio players e.g 'player' + i
for (var i = 0; i < num; i++) {
(function() {
// Variables
// ----------------------------------------------------------
// audio embed object
var playerContainer = document.getElementById('player-container'),
player = document.getElementById('player'),
isPlaying = false,
playBtn = document.getElementById('play-btn');
// Controls Listeners
// ----------------------------------------------------------
if (playBtn != null) {
playBtn.addEventListener('click', function() {
togglePlay()
});
}
// Controls & Sounds Methods
// ----------------------------------------------------------
function togglePlay() {
if (player.paused === false) {
player.pause();
isPlaying = false;
$('#play-btn').removeClass('pause');
} else {
player.play();
$('#play-btn').addClass('pause');
isPlaying = true;
}
}
}());
}
}
initPlayers(jQuery('#player-container').length);
Player code (source) on CodePen
I want some text will be shown in the same "span" that shows
"start time" (please see CodePen) while media is loading;
The text " 'loading.' 'loading..' 'loading...' " must changing on
loop while media is loading;
When it is loaded the "loading" text must be changing on "start
time" as it is now.
So basically I wat to put some text in start time while it is not shows anything but zeroes
I'm new to JS
Thats why I need some help or point to right direction
You can use the "readyState" event of the audio player to show hide loading.
There is already a "SetInterval" even which is getting fired so in that we can add this code to show/hide the "Loading"
1st add the loading element(You can put it where ever you want"
<h3 id="loading" style="display:none;">Loading</h3>
Now let's add the code to check "readystate" inside "SetInterval"
if(player.readyState>0&&player.readyState<4){
$("#loading").show();
}
else{
$("#loading").hide();
}
You can read more about "readystate" here
/As per the request I have changed the code to use the start time as loading, to make it work we don't have to add anything inside html but need to do some changes in JS
First, add this inside "togglePlay" functions pay condition in the "else" block.
$(".start-time").html("Loading...");
After this inside "initProgressBar()" function replace the "jQuery(".start-time").html(currentTime);" with the below code
if (player.readyState === 4) {
jQuery(".start-time").html(currentTime);
}
so how it will work, When you click play button the start time text will show as "Loading" but once the file is loaded and the player is ready to play the text will be changed to "start time", Hope it works. Also updated the CodePen for better understanding
You can find the full code in the CodePen
You could use setInterval to cycle through the different 'loading' text and clearInterval when the player's play promise is done.
Here's a basic example:
var dots = 1;
var loading = setInterval(function(){
dots = (dots % 3) + 1;
$(".start-time").text("Loading" + Array(dots + 1).join("."));
console.log($(".start-time").text());
}, 250);
player.play().then(function() {
clearInterval(loading);
}).catch((error) => {
$(".start-time").text("Error loading");
});
Related
I got function within JS which is supposed to show random order divs on btn click.
However once the btn is clicked user got to wait for initial 10 seconds ( which is set by: setInterval(showQuotes, 10000) ) for divs to start showing in random order which is not ideal for me.
JS:
var todo = null;
var div_number;
var used_numbers;
function showrandomdivsevery10seconds() {
div_number = 1;
used_numbers = new Array();
if (todo == null) {
todo = setInterval(showQuotes, 10000);
$('#stop-showing-divs').css("display", "block");
}
}
function showQuotes() {
used_numbers.splice(0, used_numbers.length);
$('.container').hide();
for (var inc = 0; inc < div_number; inc++) {
var random = get_random_number();
$('.container:eq(' + random + ')').show();
}
$('.container').delay(9500).fadeOut(2000);
}
function get_random_number() {
var number = randomFromTo(0, 100);
if ($.inArray(number, used_numbers) != -1) {
return get_random_number();
} else {
used_numbers.push(number);
return number;
}
}
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
Question: How to alter the code so upon the btn click divs will start showing right away without initial waiting for 10 seconds? (take in mind I want to keep any further delay of 10 seconds in between of each div being shown)
Thank you.
Call it when you begin the interval
todo = setInterval((showQuotes(),showQuotes), 10000);
I want to use a custom audio player to play sound tracks hosted online.
For example I want to be able to feed the audio player a link like
example.com/path/to/track.mp3
and it should parse it and play it. I can play sound tracks hosted locally
Here is the code where I have the problem. I have an audio object that points to a local folder where the sound tracks are. I am not sure how to deal with this when it is not hosted locally.
When I replace the path with the URL the audio player just freezes.
$(function () {
var count = 0;
var audio;
//Hide Pause
$('#pause').hide();
initAudio($('#playlist li:first-child'));
function initAudio(element) {
var song = element.attr('song');
var cover = element.attr('cover');
var artist = element.attr('artist');
var title = element.text();
var temp = parseFloat($('#volume-slider').val() / 100);
//Create audio object
audio = new Audio('../media/books/' + song);
audio.volume = temp;
audio.addEventListener("loadedmetadata", function () {
minutes = parseInt(audio.duration / 60);
seconds = parseInt(audio.duration % 60);
if (seconds < 10) {
seconds = '0' + seconds;
};
if (minutes < 10) {
minutes = '0' + minutes;
};
$('#duration').html(minutes + ':' + seconds);
});
$("#auto-play").click(function () {
if (count === 1) {
$("#auto-play").css("background-color", "black");
count = 0;
} else {
$("#auto-play").css("background-color", "rgb(0,0,255)");
count = 1;
}
});
audio.addEventListener('ended', function () {
if (count > 0) {
var next = $('#playlist li.active').next();
if (next.length == 0) {
next = $('#playlist li:first-child');
}
initAudio($(next));
audio.play();
showCurrentTime();
}
});
//Inserts track info
$('.artist').text(artist);
$('.title').text(title);
$('#duration').text();
//Insert song cover. NOTE: the path below is relative to the
//html "img.cover" element not this js file.
$('img.cover').attr('src', '../media/books/covers/' + cover);
$('#playlist li').removeClass('active');
element.addClass('active');
};
});
You can avoid CORS errors with something like this.
For your local development it would be easy.
If you would like to go in production, it would be bit harder. The Server with the soundtracks has to accept your App.
My son is doing times tables practice on this page, a timed test in which he gets 10 seconds for each sum.
https://www.timestables.com/speed-test/ - this is not my site or code, I have no direct control over the source code.
I want to give him a little more time per sum but I cannot find a way to modify the relevant code and make it work with 20 seconds instead of 10.
It looks to me like the relevant variable is maxTime (milliseconds) in this function, but nothing I do using the Chrome Developer Tools will modify this in a live running page to give 20 seconds instead of 10.
function startSom(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 10000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Can anyone suggest what to do please?
You can copy the entire method, pase it into chrome devtools and change
function startSom() {
to
window.startSom = function() {
And obviously change your time from 10000 to 20000. This changes the amount of time it allows you to answer, but not the moving progress bar which will still only take 10 seconds.
Please paste this:
window.startSom = function(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 20000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Here:
And if you want to make the progress bar following the new max Time, also paste this:
window.animateUpdate = function() {
if(bezig)
{
var now = new Date();
var timeDiff = now.getTime() - start.getTime();
if(!started){
$('#pbar_innerdiv').css("width", (100) + "%");
$('#pbar_innerdiv').animate({width: 0 + "%"},20000);
started = true;
}
perc = Math.round((timeDiff/maxTime)*100);
console.log(perc);
if(perc == 33)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF9500");
$('#pbar_innerdiv').css("borderColor", "#FF9500");
}
if(perc== 66)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF0000");
$('#pbar_innerdiv').css("borderColor", "#FF0000");
}
if (perc <= 100) {
//updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
}
else
{
bezig = false;
showTeLaat();
//alert("tijd is om");
}
}
}
There is a possibility to change files persistently in chrome devtools: Overrides.
If the script is in a seperate file you can change the maxTime directly there or if it is in a file, which needs to be reloaded you can edit any other .js and add an eventlistener there to change the startSom method on page load.
I have an issue with printing 5 different values one after another. My code is supposed to work like this:
The user presses the the start button, the timer begins, then the user presses the stop button, the timer stops and the time that has passed is printed below. The user does that 5 times and each entry below is supposed to have a different time value based on how fast the user was. (e.g. "1. you took 2.3 seconds. 2. you took 1.7 seconds. etc.).
My code seems to print the first time value, but when I couldn't get it to work with the second attempt, I've tried adding if statements to check if the first inner html label is filled, but that didn't work.
Here is my code:
var status = 0; //0:stop 1:running
var time = 0;
var f = 0;
var s = 0;
var t = 0;
var f = 0;
var f2 = 0;
function start() {
status = 1;
document.getElementById("startBtn").disabled = true;
timer();
if (f = 0) {
f + 1;
} else if (f > 0) {
s + 1;
}
}
function stop() {
if (f = 1) {
document.getElementById("first").innerHTML = time + 1;
f++;
}
if (s = 1) {
document.getElementById("second").innerHTML = time + 1;
s++;
}
status = 0;
document.getElementById("startBtn").disabled = false;
}
function reset() {
status = 0;
time = 0;
document.getElementById('timerLabel').innerHTML = '00:00:00';
document.getElementById("startBtn").disabled = false;
}
function timer() {
if (status == 1) {
setTimeout(function() {
time++;
var min = Math.floor(time / 100 / 60);
var sec = Math.floor(time / 100);
var mSec = time % 100;
if (min < 10) {
min = "0" + min;
}
if (sec >= 60) {
sec = sec % 60;
}
if (sec < 10) {
sec = "0" + sec;
}
document.getElementById('timerLabel').innerHTML = min + ":" + sec + ":" + mSec;
timer();
}, 10);
}
}
<div class="container">
<h1 class="title">Stopwatch</h1>
<h1 id="timerLabel">00:00:00</h1>
<input type="button" value="START" class="myButton" onClick="start()" id="startBtn">
<input type="button" value="STOP" class="myButton" onClick="stop()">
<input type="button" value="RESET" class="myButton" onClick="reset()">
<h2 id="first">0</h2>
<h2 id="second">0</h2>
<h2 id="third">0</h2>
<h2 id="forth">0</h2>
<h2 id="fifth">0</h2>
</div>
I see several issues right away.
First you have var f = 0 twice.
You have f + 1; and s + 1; but those statements don't return anything, you want s++; and f++; or s+=1; and f+=1; if you want the s and f variables to increment.
Your if conditions use =, which is for assignment and therefore will always return true, instead of == (equality with conversion) or better yet, === (strict equality).
Fixing those issues will probably get you up and running.
But, you've also got too much complication in this solution.
First, you should not be using inline HTML event attributes (onclick, etc.) and instead, you should be setting up all your event handling in JavaScript.
Next, it seems that you have too many variables for what you are trying to do. There really isn't a need for status as far as I can tell. If you are in the stop function, it's obvious that you are stopped. If you are in the timer function, you must be started. I also don't see the need for the f, s, f2 and t variables or the code that tracks them.
You forgot to check mSec for single digits and prepend a 0 in those cases.
Only use .innerHTML when the string you are supplying contains HTML that needs to be parsed by the browser. If there is no HTML in the string, the HTML parser will be invoked for no reason and that's a waste of resources. For non-HTML strings, use .textContent.
You also don't need to set up empty <h2> placeholders for the results ahead of time. You can create them on the fly so there will be less HTML and less JavaScript to try to test for them and match them.
Related to the <h2> comment, you should be using tags because of the semantics they convey, not because of the default formatting the browser applies to them. <h1>is fine for your page title of Stopwatch because that's a heading, but it's incorrect for showing the elapsed time because that's not a section heading. And, to show the various times between clicks, a bullet list is appropriate because you are, well, making a list. Use the right tag for the job, but then use CSS to style anything anyway that you want.
And, by separating out the code that creates the 00:00:00 string into its own function, you can call it whenever you need that format created.
I believe I've accomplished what you want below. See comments for explanations:
var time = 0; // Store the elapsed time count
var timeout = null; // Will hold a reference to the setTimeout
var lastTime = null; // Stores the time count when the stop button was last pressed
// Get all the DOM references you'll be working with, just once
// and make them available to all the functions so you don't need
// to keep finding them over and over.
var btnStart = document.getElementById("startBtn");
var btnStop = document.getElementById("stopBtn");
var btnReset = document.getElementById("resetBtn");
var timerLabel = document.getElementById('timerLabel');
var results = document.getElementById("results");
// Set up your event handlers in JavaScript, not in HTML
btnStart.addEventListener("click", start);
btnStop.addEventListener("click", stop);
btnReset.addEventListener("click", reset);
function start() {
btnStart.disabled = true;
timeout = setTimeout(function(){
time++; // Increment time count
timerLabel.textContent = getFormattedTime(time); // Update counter with formatted time
start(); // Run timer again
}, 10);
}
function stop() {
clearTimeout(timeout); // Stop the timer
var li = document.createElement("li"); // Create a new <li> element
li.textContent = getFormattedTime(time - lastTime); // Set the text for the element
lastTime = time; // Store the time that the timer stopped
results.appendChild(li); // Add the <li> to the static <ul>
btnStart.disabled = false; // Disable the start button
}
function reset(){
clearTimeout(timeout); // Stop the timer
time = 0; // Reset the time
lastTime = 0; // Reset the last time
timerLabel.textContent = '00:00:00'; // Reset the time label
btnStart.disabled = false; // Enable the start button
results.innerHTML = ""; // Clear out the static <ul>
}
// This function accepts the time count and retuns it in a 00:00:00 format
function getFormattedTime(timeVal){
var min = Math.floor(timeVal/100/60);
var sec = Math.floor(timeVal/100);
var mSec = timeVal % 100;
if(min < 10) { min = "0" + min; }
if(sec >= 60) { sec = sec % 60; }
if(sec < 10) {
if(sec === 0) {
sec = "00";
} else {
sec = "0" + sec;
}
}
if(mSec < 10) {
if(mSec === 0) {
mSec = "00";
} else {
mSec = "0" + mSec;
}
}
return min + ":" + sec + ":" + mSec;
}
/* Make elapsed time area stand out */
#timerLabel {
font-size:2em;
font-weight:bold;
margin-bottom:1em;
background-color:#ff00ff;
font-family:Arial, Helvetica, sans-serif;
display:inline-block;
padding:15px;
width:10em;
text-align:center;
}
ul { padding:0; } /* remove default indentation of list */
li { list-style-type: none; } /* remove standard bullet discs */
li::before { content: " - "; } /* place a dash before each list item instead */
<div class="container">
<h1 class="title">Stopwatch</h1>
<div id="timerLabel">00:00:00</div>
<div>
<input type="button" value="START" class="button" id="startBtn">
<input type="button" value="STOP" class="button" id="stopBtn">
<input type="button" value="RESET" class="button" id="resetBtn">
</div>
<ul id="results"></ul>
</div>
Ok I am trying to wrap up a project and the only thing holding me back is it that they call for the timer to start on clicking a match game. The timer starts when the HTML file loads which is not what the project wants and I have tried some methods but ends up freezing the game. I want the timer to be able to start when clicking a card.
var open = [];
var matched = 0;
var moveCounter = 0;
var numStars = 3;
var timer = {
seconds: 0,
minutes: 0,
clearTime: -1
};
//Start timer
var startTimer = function () {
if (timer.seconds === 59) {
timer.minutes++;
timer.seconds = 0;
} else {
timer.seconds++;
};
// Ensure that single digit seconds are preceded with a 0
var formattedSec = "0";
if (timer.seconds < 10) {
formattedSec += timer.seconds
} else {
formattedSec = String(timer.seconds);
}
var time = String(timer.minutes) + ":" + formattedSec;
$(".timer").text(time);
};
This is the code for clicking on a card. I have tried to include a startTimer code into this but doesn't work.
var onClick = function() {
if (isValid( $(this) )) {
if (open.length === 0) {
openCard( $(this) );
} else if (open.length === 1) {
openCard( $(this) );
moveCounter++;
updateMoveCounter();
if (checkMatch()) {
setTimeout(setMatch, 300);
} else {
setTimeout(resetOpen, 700);
}
}
}
};
And this class code I use for my HTML file
<span class="timer">0:00</span>
Try this: https://codepen.io/anon/pen/boWQbe
All you needed to do was remove resetTimer() call from the function that happens on page load and then just do a check in the onClick (of card) to see if the timer has started yet. timer.seconds == 0 && timer.minutes == 0.