<div class="wrapper"><div>
<div class="progress">
<!-- <svg>
<defs>
<linearGradient id="progressGradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">
<stop stop-color="#376EA6" offset="0"/><stop stop-color="#8233A4" offset="0.5"/><stop stop-color="#B34646" offset="1"/>
</linearGradient>
<filter id="insetShadow" filterunits="userSpaceOnUse">
<feFlood flood-color="#000" flood-opacity="1"></feFlood>
<feComposite in2="SourceGraphic" operator="xor"></feComposite>
<feGaussianBlur stdDeviation="3"></feGaussianBlur>
<feOffset dx="0" dy="0" result="offsetblur"></feOffset>
<feFlood flood-color="#aaa" flood-opacity="0.8"></feFlood> <feComposite in2="offsetblur" operator="atop"></feComposite>
<feComposite in2="SourceGraphic" operator="in"></feComposite>
<feMerge>
<feMergeNode in="SourceGraphic"></feMergeNode>
<feMergeNode></feMergeNode>
</feMerge>
</filter>
</defs>
<path id="container" d="M10,0 L190,0 A1,1 0 1 1 190,20 L10,20 A1,1 0 1 1 10,0 z"
fill="#fff" filter="url(#insetShadow)"/>
<path id="bar" d="M10,5 L50,5 A1,1 0 1 1 50,15 L10,15 A1,1 0 1 1 10,5 z"
fill="url(#progressGradient)">
</svg>-->
</div>
<div class="buttons">
<button onclick="$('.progress').animate({progressBar: 0})">0%</button>
<button onclick="$('.progress').animate({progressBar: 0.5})">50%</button>
<button onclick="$('.progress').animate({progressBar: 1})">100%</button>
</div>
</div></div>
html, body {
margin: 0;
background: #555;
height: 100%;
}
.wrapper {
display: table;
max-width: 980px;
width: 90%;
margin: 0 auto;
background: rgba(255,255,255,0.9);
height: 100%;
> div {
display: table-cell;
vertical-align: middle;
}
}
.progress {
width: 50%;
margin: 0 auto;
height: 40px;
// border: 1px solid #999;
}
.progress svg {
width: 100%;
height: 100%;
}
.buttons {
width: 50%;
margin: 0 auto;
}
button {
float: left;
width: 25%;
margin: 10px 25%*1/6;
border: 1px solid #ccc;
background: white;
padding: 5px 10px;
border-radius: 3px;
&:hover, &:focus {
border-color: #eaa;
background: #fee;
}
}
View Compiled
// SVG Based progress bar, example usage:
// $('.progress').progressBar({padding: 0, innerPadding: 5, progress: 0.5});
// $(window).resize(function() {
// $('.progress').progressBar('refresh');
// });
// $('.progress').progressBar('set', 0.75);
// $('.progress').css({progressBar: 0.25});
// $('.progress').animate({progressBar: 0.75}, 1000);
// Customize the way the progress bar looks with SVG embedded below
var ProgressBar = {
init: function(el, options) {
this.options = $.extend({}, ProgressBar.defaults, options);
this.$el = $(el);
if(this.$el.attr('data-progress')) {
this.options.progress = parseFloat(this.$el.attr('data-progress'));
}
this.$svg = this.$el.find('svg');
if(!this.$svg.length) {
this._createSvg();
}
this.$container = this.$svg.find('#container');
this.$bar = this.$svg.find('#bar');
this.options.supportSVGFilter = this.supportSVGFilter();
if(!this.options.supportSVGFilter) {
this.$container.attr('filter', null);
this.$container.attr('stroke-width', '1');
}
this._draw();
},
set: function(progress) {
this.options.progress = progress;
this._draw();
},
refresh: function() {
this._draw();
},
_createSvg: function() {
this.$el.html(this.svgTemplate);
this.$svg = this.$el.find('svg');
},
_draw: function() {
var containerOptions = {
pill: this.$container,
paddingY: this.options.padding,
paddingX: this.options.padding };
var barOptions = {
pill: this.$bar,
paddingY: this.options.padding + this.options.innerPadding,
paddingX: this.options.padding,
width: this.options.progress };
this._drawPill(containerOptions);
this._drawPill(barOptions);
},
_drawPill: function(options) {
var width = this.$svg.width();
var height = this.$svg.height();
var template = "M{LTP} {RTP} A1,1 0 1 1 {RBP} L{LBP} A1,1 0 1 1 {LTP} z";
var topY = options.paddingY;
var bottomY = height - options.paddingY;
var leftX = options.paddingX + height/2;
var barWidth = typeof options.width == "undefined" ?
width :
width * options.width;
barWidth = Math.max(barWidth, height + options.paddingX*2);
var rightX = barWidth - options.paddingX - height/2;
var LTP = leftX + "," + topY;
var RTP = rightX + "," + topY;
var LBP = leftX + "," + bottomY;
var RBP = rightX + "," + bottomY;
var result = template.
replace(/{LTP}/g, LTP).
replace(/{RTP}/g, RTP).
replace(/{LBP}/g, LBP).
replace(/{RBP}/g, RBP);
// console.log(result);
options.pill.attr('d', result);
}
}
$.fn.progressBar = function(options) {
var originalArguments = arguments;
this.each(function() {
var progressBar = $.data(this, 'ProgressBar');
if(!progressBar) {
progressBar = Object.create(ProgressBar);
progressBar.init(this, options);
$.data(this, 'ProgressBar', progressBar);
return;
}
if(!progressBar[options])
return;
progressBar[options](originalArguments[1]);
});
}
$.cssHooks.progressBar = {
get: function(el) {
var progressBar = $.data(el, 'ProgressBar');
if(!progressBar) return 0;
return progressBar.options.progress;
},
set: function(el, val) {
val = parseFloat(val);
var progressBar = $.data(el, 'ProgressBar');
if(!progressBar) return;
progressBar.set(val);
}
}
ProgressBar.supportSVGFilter = function() {
return typeof SVGFEColorMatrixElement !== "undefined" && SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE==2;
}
ProgressBar.defaults = {
padding: 1,
innerPadding: 4,
progress: 0
}
// Since this is SVG, it won't work in IE8.
// IE9+ supports line continuation.
ProgressBar.svgTemplate =
'<svg>\n\
<defs>\n\
<linearGradient id="progressGradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">\n\
<stop stop-color="#376EA6" offset="0"/>\n\
<stop stop-color="#8233A4" offset="0.5"/>\n\
<stop stop-color="#B34646" offset="1"/>\n\
</linearGradient>\n\
\n\
<filter id="insetShadow" filterunits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">\n\
<feFlood flood-color="#000" flood-opacity="1"></feFlood>\n\
<feComposite in2="SourceGraphic" operator="xor"></feComposite>\n\
<feGaussianBlur stdDeviation="2"></feGaussianBlur>\n\
<feOffset dx="0" dy="0" result="offsetblur"></feOffset>\n\
<feFlood flood-color="#000" flood-opacity="1"></feFlood>\n\
<feComposite in2="offsetblur" operator="atop"></feComposite>\n\
<feComposite in2="SourceGraphic" operator="in"></feComposite>\n\
<feMerge>\n\
<feMergeNode in="SourceGraphic"></feMergeNode>\n\
<feMergeNode></feMergeNode>\n\
</feMerge>\n\
</filter>\n\
</defs>\n\
\n\
<path id="container"\n\
d="M10,0 L190,0 A1,1 0 1 1 190,20 L10,20 A1,1 0 1 1 10,0 z"\n\
fill="#fff" filter="url(#insetShadow)" stroke-width="0" stroke="#CCC" />\n\
<path id="bar"\n\
d="M10,5 L50,5 A1,1 0 1 1 50,15 L10,15 A1,1 0 1 1 10,5 z"\n\
fill="url(#progressGradient)"/>\n\
</svg>';
$('.progress').progressBar({padding: 0, innerPadding: 5, progress: 0.5});
$(window).resize(function() {
$('.progress').progressBar('refresh');
});
$('.progress').progressBar('set', 0.75);
$('.progress').css({progressBar: 0.25});
$('.progress').animate({progressBar: 0.75}, 1000);
This Pen doesn't use any external CSS resources.