JSFiddle - React, Tailwind, and code Playground
HTML
<div class="text-center">
<h1>jquery.sktch-roundProgress</h1>
<form id="input">
<div class="inline-block">
<label>size</label>
<input name="size" value="175"></label>
</div>
<div class="inline-block">
<label>fillColor</label>
<input name="fillColor" value="#333"></label>
</div>
<div class="inline-block">
<label>textColor</label>
<input name="textColor" value="#333"></label>
</div>
<div class="inline-block">
<label>background</label>
<input name="background" value="#fff"></label>
</div>
<div class="inline-block">
<label>thickness</label>
<input name="thickness" value="20"></label>
</div>
<div class="inline-block">
<label>numberSize</label>
<input name="numberSize" value="50"></label>
</div>
<div class="inline-block">
<label>symbolSize</label>
<input name="symbolSize" value="20"></label>
</div>
<div class="inline-block">
<label>smooth</label>
<input name="smooth" value="100"></label>
</div>
</form>
<div class="inline-block">
<div id="roundProgress1"></div>
<p>default</p>
</div>
<div class="inline-block">
<div id="roundProgress2"></div>
<p>clean</p>
</div>
<div class="inline-block">
<div id="roundProgress3"></div>
<p>flat</p>
</div>
<div class="inline-block">
<div id="roundProgress4"></div>
<p>minimal</p>
</div>
<div class="inline-block">
<div id="roundProgress5"></div>
<p>no-text</p>
</div>
<div class="inline-block">
<div id="roundProgress6"></div>
...
CSS
.sktch-roundProgress {border-radius:50%; overflow:hidden; z-index:0; position:relative;}
.sktch-roundProgress .fillers {width:100%; height:100%;}
.sktch-roundProgress .filler {width:0; height:0; position:absolute; left:0; right:0; margin:auto; border-bottom-width:0px !important; border-style:solid; border-color:transparent; box-sizing:border-box; transform-origin: center bottom;}
.sktch-roundProgress .mask {position:absolute; top:0; bottom:0; left:0; right:0; margin:auto; border-radius:50%; overflow:hidden; border-radius:50%;}
.sktch-roundProgress .text {position:absolute; top:3px; bottom:3px; left:3px; right:3px; text-align:center; border-radius:50%;}
/* Rotation */
.sktch-roundProgress .fillers {-webkit-animation:spin 2s linear infinite; -moz-animation:spin 2s linear infinite; animation:spin 2s linear infinite; transform-origin: center center;}
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
/* default */
.sktch-roundProgress.default {background:#ededed; -webkit-box-shadow:inset 0 0 15px 0 rgba(0,0,0,.5); box-shadow:inset 0 0 15px 0px rgba(0,0,0,.5);}
.sktch-roundProgress.default .mask {-webkit-box-shadow:inset 0 0 80px 0 rgba(0,0,0,.3); box-shadow:inset 0 0 80px 0px rgba(0,0,0,.3);}
.sktch-roundProgress.default .text {border:1px solid #fff;}
/* clean */
.sktch-roundProgress.clean {background:#ededed; -webkit-box-shadow:inset 0 0 15px 0 rgba(0,0,0,.5); box-shadow:inset 0 0 15px 0px rgba(0,0,0,.5);}
/* flat */
.sktch-roundProgress.flat {background:#ededed;}
/* minimal */
/* no-text */
.sktch-roundProgress.no-text {background:#ededed;}
.sktch-roundProgress.no-text .text {display:none;}
/* line-only */
.sktch-roundProgress.line-only .text {display:none;}
body {font-weight:300; font-family:"Roboto", "Arial", sans-serif; color:#333;}
h1 {font-weight:300; font-size:60px;...
JavaScript
jQuery.fn.extend({
roundProgress: function (input) {
this.wrapper = $(this);
this.percent = 0;
this.options = {
layout : 'default',
size : 200,
fillColor : '#393',
textColor : '#393',
background : '#fff',
thickness : 20,
numberSize : 60,
symbolSize : 30,
smooth : 200,
};
this.init = function (input) {
$.extend(this.options, input);
this.createElement();
this.applyPercentage();
return this;
}
this.createElement = function(){
this.wrapper.addClass('sktch-roundProgress ' + this.options.layout);
this.wrapper.css({
width : this.options.size + 'px',
height : this.options.size + 'px',
});
this.fillers = $('<div/>', {class : 'fillers'});
var filler = $('<div/>', {class : 'filler'});
this.fillers.append(filler.clone()).append(filler.clone()).append(filler.clone()).append(filler.clone());
this.wrapper.append(this.fillers);
var maskSize = (this.options.size - (this.options.thickness * 2)) + 'px';
this.mask = $('<div/>', {class : 'mask'});
this.mask.css({background : this.options.background, width : maskSize, height : maskSize});
this.wrapper.append(this.mask);
this.percentageSpan = $('<span/>', {class : 'percentage number'});
this.symbol = $('<span/>', {class : 'percentage symbol', text : '%'});
this.symbol.css({fontSize : this.options.symbolSize + 'px'});
this.textWrapper = $('<div/>', {class : 'text'}).append(this.percentageSpan).append(this.symbol);
this.textWrapper.css({lineHeight : maskSize, color : this.options.textColor, fontSize : this.options.numberSize + 'px'});
this.mask.append(this.textWrapper);
}
...