Set range slider progress on keyup - javascript

So i got input type range, which works fine and input box, when user types number 10-500 It sets value on range and I need to set the color of progress in range. Now its showing up the previous value.
var textInputKg = document.getElementById("text");
var rangeInputKg = document.getElementById("range");
function rangeProgress(to, from) {
var min = rangeInputKg.min;
var max = rangeInputKg.max;
var value = rangeInputKg.value;
var p = ((value - min) / (max - min)) * 100;
rangeInputKg.style.backgroundImage =
"-webkit-gradient(linear, left top, right top, " +
"color-stop(" +
p +
"%, yellow), " +
"color-stop(" +
p +
"%, black)" +
")";
to.value = from.value;
}
function delay(fn, ms) {
let timer = 0;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(fn.bind(this, ...args), ms || 0);
};
}
rangeInputKg.addEventListener("input", e => {
rangeProgress(textInputKg, rangeInputKg);
});
textInputKg.addEventListener(
"keyup",
delay(e => {
rangeProgress(rangeInputKg, textInputKg);
console.log(textInputKg.value);
}, 500)
);
#range {
outline: none;
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 10px;
background: black;
}
<input id="range" type="range" max="500" min="10" value="10" autocomplete="off">
<input id="text">

Use from parameter value
var p = ((value - min) / (max - min)) * 100;
to
var p = ((from.value - min) / (max - min)) * 100;
var textInputKg = document.getElementById("text");
var rangeInputKg = document.getElementById("range");
function rangeProgress(to, from) {
var min = rangeInputKg.min;
var max = rangeInputKg.max;
var p = ((from.value - min) / (max - min)) * 100;
rangeInputKg.style.backgroundImage =
"-webkit-gradient(linear, left top, right top, " +
"color-stop(" +
p +
"%, yellow), " +
"color-stop(" +
p +
"%, black)" +
")";
to.value = from.value;
}
function delay(fn, ms) {
let timer = 0;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(fn.bind(this, ...args), ms || 0);
};
}
rangeInputKg.addEventListener("input", e => {
rangeProgress(textInputKg, rangeInputKg);
});
textInputKg.addEventListener(
"keyup",
delay(e => {
rangeProgress(rangeInputKg, textInputKg);
}, 500)
);
#range {
outline: none;
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 10px;
background: black;
}
<input id="range" type="range" max="500" min="10" value="10" autocomplete="off">
<input id="text">

Related

Why do my Elements have this weird offset?

Hello Stackoverflow Users, so I am making a game with HTML, I have to eat berries, but when I collect them, the more I collect (the max is 5), the more offset the extra body parts add to all of the body parts (minus the main one).
I have tried changing offset with the variables and loop I used, but nothing worked, no matter the math operator.
All of jQuery code:
// Null Variables \\
/* These variables have no value. */
var bound;
var newFood;
var horizontalMatch;
var vertialMatch;
// Main Variables \\
/* These variables keep values in store. */
var background = $(".game-background");
var player = $(".game-player");
var verticalNum = 0;
var horizontalNum = 0;
var score = 0;
var speed = 20;
var updatePos = 0;
var numOfSnakes = 0;
var snakesArray = [];
// Main Functions \\
/* These are all of the function being called, and created. */
updateSnakeCSS = function (snakes) {
if (snakes.length > -1) {
//for (var i = 0; i < snakes.length; i++) {
console.log(snakes[numOfSnakes - 1]);
$("." + snakes[numOfSnakes - 1]).css("position", "absolute");
$("." + snakes[numOfSnakes - 1]).css("left", player.offset().left - 20);
$("." + snakes[numOfSnakes - 1]).css("top", player.offset().top);
$("." + snakes[numOfSnakes - 1]).css("border", "black");
$("." + snakes[numOfSnakes - 1]).css("border-style", "outset");
$("." + snakes[numOfSnakes - 1]).css("border-width", 2 + "px");
$("." + snakes[numOfSnakes - 1]).css("width", player.width());
$("." + snakes[numOfSnakes - 1]).css("height", player.height());
$("." + snakes[numOfSnakes - 1]).css("background-color", "red");
//}
}
};
addSnake = function (snakes) {
if (numOfSnakes < 5) {
var body = document.getElementsByTagName("body")[0];
var newBodyPart = document.createElement("div");
newBodyPart.className = "game-player" + numOfSnakes;
body.appendChild(newBodyPart);
snakes.push("game-player" + numOfSnakes);
console.log(updatePos);
numOfSnakes++;
}
};
updateScore = function () {
score++;
$(".game-scoreboard").text("Berries: " + score);
};
createFood = function ($parentDiv) {
if (newFood == null) {
var x = WMath.random(220, background.width() * 1.5 - 100);
var y = WMath.random(100, background.height());
var body = document.getElementsByTagName("body")[0];
newFood = document.createElement("div");
newFood.className = "game-food";
body.appendChild(newFood);
$(".game-food").css("width", player.width() / 2);
$(".game-food").css("border", "black");
$(".game-food").css("border-style", "outset");
$(".game-food").css("border-width", 1 + "px");
$(".game-food").css("height", player.width() / 2);
$(".game-food").css("background-color", "red");
$(".game-food").css("position", "absolute");
$(".game-food").css("left", x);
$(".game-food").css("top", y);
}
};
var WMath = {
random: function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive
},
};
var WObject = {
isTouching: function ($div1, $div2) {
var x1 = $div1.offset().left;
var y1 = $div1.offset().top;
var h1 = $div1.outerHeight(true);
var w1 = $div1.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $div2.offset().left;
var y2 = $div2.offset().top;
var h2 = $div2.outerHeight(true);
var w2 = $div2.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
console.log("Touching WObject");
newFood = null;
createFood(document.body);
updateScore();
addSnake(snakesArray);
updateSnakeCSS(snakesArray);
speed += 2;
$div2.remove();
return true;
},
};
createFood(document.body);
$(document).keyup(function (e) {
var key = e.keyCode || e.which;
const keys = {
UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,
};
if (key === keys.UP && verticalNum > 0 && !String(verticalNum).includes("e")) {
verticalNum -= speed;
if (verticalNum < 0) {
verticalNum = 0;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("top", player.offset().top + i * 23 + updatePos);
$("." + snakesArray[i]).css("left", player.offset().left + updatePos);
}
}
$(".game-player").css("top", verticalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.DOWN && verticalNum < 475.8000000000002) {
verticalNum += speed;
if (verticalNum > 475.8000000000002) {
verticalNum = 475.8000000000002;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("top", player.offset().top - i * 23 - updatePos);
$("." + snakesArray[i]).css("left", player.offset().left - updatePos);
}
}
$(".game-player").css("top", verticalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.LEFT && horizontalNum > 0 && !String(horizontalNum).includes("e")) {
horizontalNum -= speed;
if (horizontalNum < 0) {
horizontalNum = 0;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("left", player.offset().left + i * 23 + updatePos);
$("." + snakesArray[i]).css("top", player.offset().top + updatePos);
}
}
$(".game-player").css("left", horizontalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
} else if (key === keys.RIGHT && horizontalNum < 475.8000000000002) {
horizontalNum += speed;
if (horizontalNum > 475.8000000000002) {
horizontalNum = 475.8000000000002;
}
if (snakesArray.length > -1) {
for (var i = 0; i < snakesArray.length; i++) {
$("." + snakesArray[i]).css("left", player.offset().left - i * 23 - updatePos);
$("." + snakesArray[i]).css("top", player.offset().top - updatePos);
}
}
$(".game-player").css("left", horizontalNum);
WObject.isTouching($(".game-player"), $(".game-food"));
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GAME</title>
<style>
.game-background {
background-color: lightgray;
width: 500px;
height: 500px;
position: absolute;
top: 55px;
left: 200px;
border: black;
border-style: solid;
border-width: 10px;
}
.game-player {
background-color: blue;
width: 20px;
height: 20px;
position: relative;
top: 0px;
left: 0px;
border: black;
border-style: inherit;
border-width: 2px;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="game-scoreboard">Berries: 0</p>
<div class="game-background">
<div class="game-player"></div>
</div>
<script>
// The Script shown in the JavaScript
</script>
</body>
</html>
It's because of:
speed += 2;
Remove it and it will work fine.
As you're using speed in calculating the verticalNum and horizontalNum everytime, so it increments it with 2 each time, giving a wrong position.
The output after removing it:

Price and Discount Intervals Calculator

This code below applies a percentage discount.
How is it possible to adjust to apply discount intervals, in $? (according to attached images and Excel files)
Example :
N° Services: 0-9 / You Save: 0
N° Services: 10-19 / You Save: 360,00
N° Services: 20-29 / You Save: 720,00
N° Services: 30-39 / You Save: 1.080,00
N° Services: 40-49 / You Save: 1.440,00
N° Services: 50-59 / You Save: 1.800,00
N° Services: 60-69 / You Save: 2.160,00
N° Services: 70-79 / You Save: 2.520,00
N° Services: 80-89 / You Save: 2.880,00
N° Services: 90-99 / You Save: 3.240,00
window.onload = function () {
var $ = function (selector) {
return document.querySelector(selector);
};
var update = function () {
var amount = $range.value;
var cost = 10;
var percent = 30;
var discount = (amount * (percent / $range.max)).toFixed(2);
var total = cost * amount - discount / 10 * amount;
$amount.innerHTML = 'Number of Sharpenings: ' + amount;
$discount.innerHTML = 'Discount: ' + discount + '%';
$total.innerHTML = 'Total: $' + total.toFixed(2);
};
var $range = $('.range');
var $amount = $('.amount');
var $discount = $('.discount');
var $total = $('.total');
update();
$range.addEventListener('input', update);
$range.addEventListener('change', update);
};
<style class="INLINE__ID">
.wrapper {
max-width: 600px;
width: 100%;
margin: 0 auto;
}
.wrapper .range {
width: 100%;
}
.wrapper .discount {
color: #999;
border-bottom: 1px solid #efefef;
padding-bottom: 15px;
}
</style>
<div class="wrapper">
<h1 class="title">Price Calculator</h1>
<h3 class="amount">Number of Sharpenings: 100</h3>
<input class="range" type="range" min="0" max="100" value="0" step="1">
<h3 class="discount">Discount: 30.00%</h3>
<h2 class="total">Total: $700.00</h2>
</div>
Use Mathematics in your favor. The Save brackets table is, in reality, a function which increments 360 every 10 steps:
y = (x \ 10) * 360
which you can translate to:
function getSaveAmount(count){
return Math.floor(count / 10) * 360;
}
If it gets more complex, you can put those brackets in an array with values being entire discounts, sets, use switch/cases, if's, etc..
window.onload = function () {
var $ = function (selector) {
return document.querySelector(selector);
};
var getSaveAmount = function (count){
return Math.floor(count / 10) * 360;
}
var update = function () {
var amount = $range.value;
var cost = 10;
var percent = 30;
var discount = (amount * (percent / $range.max)).toFixed(2);
var total = cost * amount - discount / 10 * amount;
$amount.innerHTML = 'Number of Sharpenings: ' + amount;
$discount.innerHTML = 'Discount: ' + discount + '%';
$total.innerHTML = 'Total: $' + total.toFixed(2);
$save.innerHTML = 'Total: $' + getSaveAmount(amount).toFixed(2);
};
var $range = $('.range');
var $amount = $('.amount');
var $discount = $('.discount');
var $total = $('.total');
var $save = $('.save');
update();
$range.addEventListener('input', update);
$range.addEventListener('change', update);
};
<style class="INLINE__ID">
.wrapper {
max-width: 600px;
width: 100%;
margin: 0 auto;
}
.wrapper .range {
width: 100%;
}
.wrapper .discount {
color: #999;
border-bottom: 1px solid #efefef;
padding-bottom: 15px;
}
</style>
<div class="wrapper">
<h1 class="title">Price Calculator</h1>
<h3 class="amount">Number of Sharpenings: 100</h3>
<input class="range" type="range" min="0" max="100" value="0" step="1">
<h3 class="discount">Discount: 30.00%</h3>
<h2 class="total">Total: $700.00</h2>
<p class="save">Save: </p>
</div>

Is there a way to combine multiple divs into one

I have a dynamic group of n by m divs to form a grid. The items in this grid can be selected. The end result which I am hoping to achieve is to be able to combine and split the selected divs.
I have managed to get the divs to show correctly and select them, storing their id's in a list. Is there a way I could combine the selected divs, keeping the ones around it in their place?
#(Html.Kendo().Window()
.Name("window") //The name of the window is mandatory. It specifies the "id" attribute of the widget.
.Title("Dashboard Setup") //set the title of the window
.Content(#<text>
<div id="divSetup">
<div class="dvheader">
<b>Dashboard Setup</b>
</div>
<div>
<p>Enter the number of columns and rows of dashboard elements. This will create an empty dashboard with a set number of items which can be filled with KPI charts.</p>
<br />
<div class="dvform">
<table>
<tr style="margin-bottom: 15px;">
<td>
#Html.Label("Number of Columns: ")
</td>
<td>
<input type="number" name="NumColumns" id="NoColumns" min="1" max="20" />
</td>
</tr>
<tr style="margin-bottom: 15px;">
<td>
#Html.Label("Number of Rows: ")
</td>
<td>
<input type="number" name="NumRows" id="NoRows" min="1" max="20" />
</td>
</tr>
</table>
</div>
</div>
<div style="float: right">
<button id="btnSave" class="k-primary">Save</button>
<button id="btnClose">Close</button>
</div>
</div>
</text>)
.Draggable() //Enable dragging of the window
.Resizable() //Enable resizing of the window
.Width(600) //Set width of the window
.Modal(true)
.Visible(false)
)
<div id="dashboard">
</div>
<button id="combine" title="Combine">Combine</button>
<script>
$(document).ready(function () {
debugger;
$("#window").data("kendoWindow").open();
$("#btnClose").kendoButton({
click: close
});
$("#btnSave").kendoButton({
click: Save
});
$("#combine").kendoButton();
});
var array = [];
function clicked(e)
{
debugger;
var selectedDiv = "";
var x = document.getElementsByClassName('column')
for (var i = 0; i < x.length; i++)
{
if (x[i].id == e.id)
{
x[i].classList.add("selected");
array.push(x[i]);
}
}
for (var x = 0; x < array.length - 1; x++) {
array[x].classList.add("selected");
}
}
function close() {
$("#window").hide();
}
function Save()
{
debugger;
var col = document.getElementById("NoColumns").value;
var row = document.getElementById("NoRows").value;
for (var x = 1; x <= row; x++)
{
debugger;
document.getElementById("dashboard").innerHTML += '<div class="row">';
debugger;
for (var i = 1; i <= col; i++)
{
document.getElementById("dashboard").innerHTML += '<div onclick="clicked(this)" id="Row ' + x + ' Col ' + i + '" class="column">' + i + '</div>';
}
document.getElementById("dashboard").innerHTML += '</div>';
}
}
<style>
.selected {
background-color: #226fa3;
transition: background-color 0.4s ease-in, border-color 0.4s ease-in;
color: #ffffff;
}
#dashboard {
width: 80%;
margin: auto;
background-color: grey;
padding: 20px;
}
* {
box-sizing: border-box;
}
/* Create three equal columns that floats next to each other */
.column {
float: left;
padding: 20px;
border: 1px black solid;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
Below is an image of the selected blocks I would like to combine into one, while keeping it's place
If you were using a table it would be much easier, for div's, I can think of a solution if the style position is absolute, maybe it would help you start at least.
<div id="container"></div>
<button id="combine" title="Combine" disabled="disabled">Combine</button>
<div id="output"></div>
the script:
<script>
var cc;
function group() {
var xx = $(".selected").map(function () { return $(this).attr("data-x"); }).get();
var yy = $(".selected").map(function () { return $(this).attr("data-y"); }).get();
this.minX = Math.min.apply(Math, xx);
this.minY = Math.min.apply(Math, yy);
this.maxX = Math.max.apply(Math, xx);
this.maxY = Math.max.apply(Math, yy);
this.selectedCount = $(".selected").length;
this.CorrectGroup = function () {
var s = this.selectedCount;
return s == this.cellsCount() && s > 1;
}
this.width = function () {
return this.maxX - this.minX + 1;
}
this.height = function () {
return this.maxY - this.minY + 1;
}
this.cellsCount = function () {
return this.width() * this.height();
}
}
function cell(x, y, g) {
this.x = x;
this.y = y;
this.g = g;
this.spanX = 1;
this.spanY = 1;
this.visible = true;
var cellWidth = 80;
var cellHeight = 50;
this.div = function () {
var output = jQuery('<div/>');
output.attr('id', 'y' + y + 'x' + x);
output.attr('data-x', x);
output.attr('data-y', y);
output.attr('style', this.left() + this.top() + this.width() + this.height());
output.addClass('clickable');
output.html('(y=' + y + ' x=' + x + ')')
return output;
}
this.left = function () {
return 'left:' + (x * cellWidth) + 'px;';
}
this.top = function () {
return 'top:' + (100 + y * cellHeight) + 'px;';
}
this.width = function () {
return 'width:' + (this.spanX * cellWidth) + 'px;';
}
this.height = function () {
return 'height:' + (this.spanY * cellHeight) + 'px;';
}
}
function cells(xx, yy) {
this.CellWidth = xx;
this.CellHeight = yy;
this.CellList = [];
for (var y = 0; y < yy; y++)
for (var x = 0; x < xx; x++) {
this.CellList.push(new cell(x, y, 1));
}
this.findCell = function (xx, yy) {
return this.CellList.find(function (element) {
return (element.x == xx && element.y == yy);
});
}
this.displayCells = function (container) {
container.html('');
for (var y = 0; y < yy; y++)
for (var x = 0; x < xx; x++) {
var cell = this.findCell(x, y);
if (cell.visible)
cell.div().appendTo(container);
}
}
}
$(document).ready(function () {
$('#combine').click(function () {
$(".selected").each(function () {
var x = $(this).data('x');
var y = $(this).data('y');
var cell = cc.findCell(x, y);
cell.visible = false;
cell.g = 'y';
});
var first = $(".selected").first();
var xx = $(first).data('x');
var yy = $(first).data('y');
var cell = cc.findCell(xx, yy);
var g = new group();
cell.visible = true;
cell.g = xx + '_' + yy;
cell.spanX = g.width();
cell.spanY = g.height();
cc.displayCells($('#container'));
});
//make divs clickable
$('#container').on('click', 'div', function () {
$(this).toggleClass('selected');
if (CheckIfSelectedAreGroupable())
$('#combine').removeAttr("disabled");
else
$('#combine').attr("disabled", "disabled");
});
cc = new cells(12, 10);
cc.displayCells($('#container'));
});
function CheckIfSelectedAreGroupable() {
var g = new group();
return g.CorrectGroup();
}
</script>
Style:
<style>
.selected {
background-color: #226fa3 !important;
transition: background-color 0.4s ease-in, border-color 0.4s ease-in;
color: #ffffff;
}
.clickable {
border: 1px solid lightgray;
margin: 0px;
padding: 0px;
background-color: lightyellow;
position: absolute;
}
</style>
Im starting the divs by the following line, you can hock your form to trigger something similar.
cc = new cells(12, 10);
the combine button will not activate if you dont select a correct group, a rectangle shape selection.
the split will not be hard too but I did not have time to put it together, if this solution help, I can update it for the split.
Note: I wrote this quickly so its not optimized.
to try the solution use :
jsfiddle

Getting a random variable blur in my css

I want the result of the math function into my css file, that the kind of blur is variable. But it doesn't work and I don't know how, because there are no errors. The variable number is between 1 and 5.
This is the Javascript code I'm using:
var minNumber = 1;
var maxNumber = 5;
var result;
var randomNumber = randomNumberFromRange(minNumber, maxNumber);
function randomNumberFromRange(min, max) {
result = Math.floor(Math.random() * (max - min + 1) + min);
return;
}
document.getElementById("test").style.filter = blur(result + "px");
Set that style as a string:
document.getElementById("test").style.filter = "blur(" + result + "px)";
var minNumber = 1;
var maxNumber = 5;
var result;
var randomNumber = randomNumberFromRange(minNumber, maxNumber);
function randomNumberFromRange(min, max) {
result = Math.floor(Math.random() * (max - min + 1) + min);
}
document.getElementById("test").style.filter = "blur(" + result + "px)";
#test {
position: absolute left: 10px;
top: 10px;
background-color: lightgreen;
width: 200px;
height: 200px;
z-index: 9999;
opacity: .9;
}
#test2 {
position: absolute;
left: 30px;
top: 40px;
background-color: black;
width: 100px;
height: 100px;
}
<div id="test">
</div>
<div id="test2"></div>
Check your console. You should have an error saying blur is undefined.
blur is not a function defined in JS, but rather a CSS filter function, and as such should be set as a string in your case.
For example:
document.getElementById("test").style.filter = 'blur('+result+'px)';
If ES6 is possible in your case, you can also use a template string and plug the value as an embedded expression:
document.getElementById("test").style.filter = `blur(${result}px)`;
You need to pass blur as a text value to the CSS filter property:
var minNumber = 1;
var maxNumber = 5;
var result;
var randomNumber = randomNumberFromRange(minNumber, maxNumber);
function randomNumberFromRange(min, max) {
result = Math.floor(Math.random() * (max - min + 1) + min);
return;
}
console.log('random value for blur: ', result);
document.getElementById("test").style.filter = 'blur('+ result +'px)';
<p id="test">test</p>

How to show minute, second, hour in time progress bar

I have a time progress bar. I use this code. In this time bar, I get the time in seconds, but I want to show minute, second, hour in the time progress bar.
var timer = 0,
timeTotal = 2500,
timeCount = 20,
timeStart = 0,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text((percentage / 1000).toFixed(2) + "\00a0s");
}
function animateUpdate() {
var perc = new Date().getTime() - timeStart;
if(perc < timeTotal) {
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
} else {
updateProgress(timeTotal);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
cFlag = true;
timeStart = new Date().getTime();
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
jsfiddle.net/McNetic/hnfRe/397
You can try this. DEMO LINK HERE
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0 s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
JS...
var timer = 0,
timeTotal = 250000,
timeCount = 20,
timeStart = 0,
cFlag;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
var totalSec= (percentage / 1000);
var min = parseInt(totalSec/60);
var sec = parseInt(totalSec%60);
var hr= parseInt(min/60);
min = parseInt(min % 60);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text(hr+":"+min+":"+sec + "");
}
function animateUpdate() {
var perc = new Date().getTime() - timeStart;
if(perc < timeTotal) {
updateProgress(perc);
timer = setTimeout(animateUpdate, timeCount);
} else {
updateProgress(timeTotal);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag == undefined) {
clearTimeout(timer);
cFlag = true;
timeStart = new Date().getTime();
animateUpdate();
}
else if (!cFlag) {
cFlag = true;
animateUpdate();
}
else {
clearTimeout(timer);
cFlag = false;
}
});
});
CSS...
#pbar_outerdiv { cursor: pointer; }
With percentaje (line 11):
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text(x.toFixed(2) + '%');
}
SEE DEMO
With hours, minutes and seconds:
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress(percentage) {
var x = (percentage/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(percentage/hours) + 'h ' + Math.floor(percentage/minutes) + 'm ' + Math.floor(percentage/seconds) + 's');
}
SEE DEMO.
I think for that you should use requestAnimationFrame:
var timeTotal = 2500,
timeStart = 0,
cFlag = false;
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress() {
var time = new Date().getTime() - timeStart;
var x = (time/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(time/hours) + 'h ' + Math.floor(time/minutes) + 'm ' + Math.floor(time/seconds) + 's');
if(time <= timeTotal && cFlag) {
requestAnimationFrame(updateProgress);
}
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag === false) {
cFlag = true;
timeStart = new Date().getTime();
updateProgress();
}
else {
cFlag = false;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0h 0m 0s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
UPDATED WITH PAUSE ALLOW AND RESUME:
var timeTotal = 5 * minutes,
timePaused = 0,
timePausedStart = 0,
timeStart = 0,
cFlag = false,
stopped = false;
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
function updateProgress() {
if( !timePausedStart ) { // if not paused
var time = new Date().getTime() - timeStart - timePaused;
var x = (time/timeTotal)*100,
y = x.toFixed(3);
$('#pbar_innerdiv').css("width", x + "%");
$('#pbar_innertext').css("left", x + "%").text( Math.floor(time/hours%24) + 'h ' + Math.floor(time/minutes%60) + 'm ' + Math.floor(time/seconds) + 's');
if(time > timeTotal) {
cFlag = false;
}
if( Math.floor(time/seconds) == 3*60+30 && !stopped){ // pause at 3 m 30 s
stopped = true;
pause();
}
}
if( cFlag )
requestAnimationFrame(updateProgress);
}
$(document).ready(function() {
$('#pbar_outerdiv').click(function() {
if (cFlag === false) {
cFlag = true;
timeStart = new Date().getTime();
timePaused = 0;
updateProgress();
} else if( cFlag === true && timePausedStart ){ // reset pause
timePaused += new Date().getTime() - timePausedStart;
timePausedStart = 0;
}
else {
pause();
}
});
});
var pause = function(){
timePausedStart = new Date().getTime();
};
#pbar_outerdiv { cursor: pointer; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pbar_outerdiv" style="width: 300px; height: 20px; border: 1px solid grey; z-index: 1; position: relative; border-radius: 5px; -moz-border-radius: 5px;">
<div id="pbar_innerdiv" style="background-color: lightblue; z-index: 2; height: 100%; width: 0%;"></div>
<div id="pbar_innertext" style="z-index: 3; position: absolute; top: 0; left: 0; height: 100%; color: black; font-weight: bold; text-align: center;">0h 0m 0s</div>
</div>
<p>Click once to start!</p>
<p>Click again to toggle Start/Stop</p>
Instead of printing (percentage / 1000).toFixed(2), you can use percentage to split your time in millisecond to h:m's.ms
You can simply compute the desired values with integer divisions
h = Math.floor(percentage / 3600000);
m = Math.floor((percentage - h * 3600000) / 60000);
s = Math.floor((percentage - h * 3600000 - m * 60000) / 1000);
ms = Math.floor(percentage - h * 3600000 - m * 60000 - s * 1000);
Then, you can just use toString() to convert your int to strings. I concatenated the values with 0 and and used slice() to keep only the two last character. This allow you to print hours, minutes, ... in two digits format
text = ("0" + h.toString() ).slice(-2) + ":" +
("0" + m.toString() ).slice(-2) + "'" +
("0" + s.toString() ).slice(-2) + "\"" +
("0" + ms.toString()).slice(-2);

Categories

Resources