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>
Related
var time = 0;
function Gravity(id){
var that = this;
var element = document.getElementById(id);
var text = element.textContent;
var arr = text.split('');
this.animate = true;
this.floating = true;
this.resetTime = 0;
this.positionType = getComputedStyle(element).position;
this.lerp = function (e,t,i){
return(1-i)*e+i*t;
}
this.checkBound = function(){
if (element.hasAttribute("data-bound")) {
return element.dataset.bound === "false";
}
}
this.useBound = this.checkBound();
this.colors = [
'#fff','#fff','#fff',
'#fff','#fff','#fff',
'#fff','#fff','#fff',
'#fff','#fff','#fff',
'#fff','#fff','#fff',
'#fff','#fff','#fff',
'#fff'
];
this.randomColor = function(){
var randNum = Math.floor(Math.random() * this.colors.length);
return this.colors[randNum];
}
this.bounds = this.useBound ? {
min : {
x : element.offsetLeft,
y : element.offsetTop
},
max : {
x : element.offsetLeft + element.offsetWidth,
y : element.offsetTop + element.offsetHeight
}
} : {
min : {
x : 0,
y : 0
},
max : {
x : window.innerWidth,
y : window.innerHeight
}
}
this.pointInCircle = function(point, target, radius) {
var distsq = (point.x - target.x) * (point.x - target.x) + (point.y - target.y) * (point.y - target.y);
return [distsq <= radius * radius, distsq];
}
function createSpan(text,pos){
var span = document.createElement('span');
span.innerHTML = text;
span.style.position = "relative";
span.style.display = "inline-block";
span.style.minWidth = "10px";
span.style.color = that.randomColor();
span._own = {
pos : {
x : 0,
y : 0
},
vel : {
x : -0.5 + Math.random(),
y : -0.5 + Math.random()
},
speed : {
x : 1,
y : 1
},
dir : {
x : 1,
y : 1
}
}
return span;
}
this.textSpans = [];
element.innerHTML = '';
arr.forEach(function(t,i){
var el = createSpan(t,{
x : 0,
y : 0
});
element.appendChild(el);
that.textSpans.push(el);
});
this.getDim = function(){
this.textSpans.forEach(function(t,i){
var offset = {
x : 0,
y : 0
}
if(that.positionType === 'relative' || that.positionType === 'absolute'){
offset.x = element.offsetLeft
offset.y = element.offsetTop
}
t._own.real = {
x : offset.x +t.offsetLeft,
y : offset.y +t.offsetTop
},
t._own.size = {
x : t.offsetWidth,
y : t.offsetHeight
}
});
};
this.getDim();
this.floatText = function(){
this.textSpans.forEach(function(t,i){
if(t._own.pos.x + t._own.real.x < that.bounds.min.x || t._own.pos.x + t._own.real.x + t._own.size.x > that.bounds.max.x){
t._own.dir.x *= -1;
}
if(t._own.pos.y + t._own.real.y < that.bounds.min.y || t._own.pos.y + t._own.real.y + t._own.size.y > that.bounds.max.y){
t._own.dir.y *= -1;
}
t._own.pos.x += (t._own.vel.x * t._own.speed.x) * t._own.dir.x;
t._own.pos.y += (t._own.vel.y * t._own.speed.y) * t._own.dir.y;
t.style.transform = 'translateX('+ t._own.pos.x +'px) translateY('+ t._own.pos.y +'px)';
});
}
this.update = function(){
if(this.animate){
if(this.floating){
this.floatText();
}else{
this.floatBackwards();
}
}
}
this.floatBackwards = function(){
this.textSpans.forEach(function(t,i){
var x = that.lerp(t._own.pos.x,0, that.resetTime / 10);
var y = that.lerp(t._own.pos.y,0, that.resetTime / 10);
t.style.transform = 'translateX('+ x +'px) translateY('+ y +'px)';
});
if(this.resetTime===10){
this.animate = false;
this.resetTime = 0;
}
this.resetTime++;
}
this.reset = function(){
this.floating = false;
}
this.restart = function(){
this.textSpans.forEach(function(t,i){
t._own.pos.x = 0;
t._own.pos.y = 0;
});
this.floating = true;
this.animate = true;
}
window.onresize = function(){
that.getDim();
}
}
var paragraph = new Gravity('text');
var gravity = new Gravity('reset');
var button = document.getElementById('reset');
button.addEventListener('click',function(){
if(gravity.animate){
gravity.reset();
paragraph.reset();
}else{
gravity.restart();
paragraph.restart();
}
});
var render = function (time) {
requestAnimationFrame( render );
animation(time);
};
//__________ animation
function animation(time){
paragraph.update();
gravity.update();
};
//__________
render(time);
body {
background-color: black;
}
/* NAMES */
button {
position: fixed;
bottom: 0rem;
left: 0px;
padding: 2rem 2rem 2rem 6rem;
font-size: 1vh;
background-color: white;
border: 0px;
z-index: 20;
text-decoration: none;
}
.article {
height: 100vh;
width: 100vw;
z-index: 20;
display: flex;
word-wrap: normal;
}
.names {
width: 50vw;
height: 50vh;
margin: auto;
text-align: center;
font-size: 1rem;
z-index: 20;
word-wrap: normal;
text-align: justify;
text-justify: inter-word;
}
.reset {
padding: 10rem;
background-color: white;
z-index: 20;
}
<body>
<!-- NAMES -->
<div class="article">
<div id="text" class="names">
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
<p>Name Family Name</p>
</div>
<button id="reset" data-bound="true"></button>
</div>
</body>
I'm working on a website in which the names and letters are floating and moving around. I'd like to add links to names for info in a pop up or something similar. When you enter the names will start floating and then when you click on the "red button" they will gather and you'll be able to read them.
I'm not sure why I can't add links, but I guess it might be some part of the JavaScript code, but I don't know which part I have to change to be able to make it work.
Any help will be much appreciated. Thank you!
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">
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
I use Ion.RangeSlider for my Project but and I need to change slider range to RTL.
How can I do this work?
Jquery code:
<script>
var $range = $(".js-range-slider");
var $result = $(".js-result");
var $result2 = $(".js-result2");
var minrange = 0;
var minrange_title = 69000;
var maxrange = 4596800;
var avreg = (maxrange/100);
var avregfinal = (avreg * 10);
var avff = Math.ceil(avregfinal);
function prettify(num) {
var n = num.toString();
return n.replace(/(\d{1,3}(?=(?:\d\d\d)+(?!\d)))/g, "$1" + "," );
}
$range.ionRangeSlider({
type: "double",
grid: false,
min: minrange_title,
max: maxrange,
from: minrange_title,
to: maxrange,
step: (avff - minrange_title),
hide_min_max: true,
hide_from_to: true,
prettify_separator: ",",
onStart: function(data) {
$result.text(prettify(data.from));
$result2.text(prettify(data.to));
},
onChange: function(data) {
$result.text(prettify(data.from));
$result2.text(prettify(data.to));
}
});
</script>
HTML and Css code:
<style>
.range-slider {
position: relative;
height: 80px;
width: 210px !important;
margin: auto;
}
.extra-controls {
font-size: 9pt;
position: relative;
float: left;
padding: 10px 0 0;
text-align: right;
color: #4d4d4d;
}
.extra-controls2 {
position: relative;
float: right;
padding: 10px 0 0;
font-size: 9pt;
color: #4d4d4d;
}
</style>
<div class="range-slider">
<input type="text" class="js-range-slider" value="" />
<div class="yekan toman extra-controls js-result">
</div>
<div class="yekan toman extra-controls2 js-result2">
</div>
</div>
I need to change code for this slider range and I do not like to choose another slider range.
http://ionden.com/a/plugins/ion.rangeSlider/en.html
Thanks.
http://jsfiddle.net/SinaSaderi/Ldbr343s/
var $range = $(".js-range-slider"),
min = 10,
max = 70;
$range.ionRangeSlider({
type: "single",
min: min,
max: max,
from: max - 20 + min,
prettify: function(num) {
var tmp_min = min,
tmp_max = max,
tmp_num = num;
if (min < 0) {
tmp_min = 0;
tmp_max = max - min;
tmp_num = num - min;
tmp_num = tmp_max - tmp_num;
return tmp_num + min;
} else {
num = max - num + min;
return num;
}
}
});
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);