Skip to content

Instantly share code, notes, and snippets.

@kangax
Forked from maxim/progressify.rb
Created June 28, 2011 16:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kangax/1051534 to your computer and use it in GitHub Desktop.
Save kangax/1051534 to your computer and use it in GitHub Desktop.
Progressify - a progress bar approximator for smoothness
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Progressify</title>
<script>
var Plot = (function() {
function Point(duration, progress) {
this.duration = duration;
this.progress = progress;
}
function Plot() {
this.points = [ ];
this.prevProgress = 0;
}
Plot.prototype.STARTING_SLOPE = 4;
Plot.prototype.addPoint = function(duration, progress) {
if (this.actualProgressIncreased(progress)) {
this.points.push(new Point(duration, progress));
}
};
Plot.prototype.progressAt = function(duration) {
var newProgress;
if (this.points.length !== 0 && this.points[this.points.length - 1].progress >= 100) {
newProgress = 100;
}
else {
newProgress = this.calcProgress(duration);
}
newProgress = Math.max(this.prevProgress, Math.round(newProgress));
this.prevProgress = newProgress;
return newProgress;
};
Plot.prototype.calcProgress = function(duration) {
return Math.min(99, (duration * this.averageSlope()));
};
Plot.prototype.actualProgressIncreased = function(progress) {
var prevProgress = this.points[this.points.length - 1]
? this.points[this.points.length - 1].progress
: 0;
return progress > prevProgress;
};
Plot.prototype.slopes = function() {
var slopes = [this.STARTING_SLOPE];
for (var i = 0, len = this.points.length; i < len; i++) {
var point = this.points[i];
var prevDuration = (i == 0 ? 0 : this.points[i - 1].duration);
var prevProgress = (i == 0 ? 0 : this.points[i - 1].progress);
slopes.push((point.progress - prevProgress) / (point.duration - prevDuration))
}
return slopes;
};
Plot.prototype.averageSlope = function() {
var sum = 0;
for (var i = 0, slopes = this.slopes(), len = slopes.length; i < len; i++) {
sum += slopes[i];
}
return sum / slopes.length;
};
return Plot;
})();
</script>
</head>
<body>
<progress value="0" max="100"></progress>
<script>
var sample1 = [ [2, 9 ],
[5, 50 ],
[5, 75 ],
[3, 100 ] ];
var sample2 = [ [5, 15 ],
[2, 30 ],
[4, 45 ],
[3, 65 ],
[6, 100 ] ]
var sample3 = [ [1, 1 ],
[5, 50 ],
[5, 100 ] ];
var sample4 = [ [1, 0 ],
[10, 25 ],
[2, 100 ] ];
var sample = sample4;
var plot = new Plot();
var pollingDuration = 0;
var progressEl = document.getElementsByTagName('progress')[0];
function fetchFromSample() {
var pair = sample.shift();
var interval = pair[0];
var progress = pair[1];
setTimeout(function() {
pollingDuration += interval;
plot.addPoint(pollingDuration, progress);
if (sample.length > 0) {
fetchFromSample();
}
}, interval * 1000);
}
var startTime = new Date();
fetchFromSample();
var interval = setInterval(function() {
var value = plot.progressAt((new Date - startTime) / 1000);
if (value === 100) {
clearInterval(interval);
}
progressEl.value = value;
}, 100);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment