JSFiddle - React, Tailwind, and code Playground
by Nikita Polevoy
HTML
<script src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h3>PhotoShop</h3>
<div class="skillbar" data-percent="79%">
<div class="skillbar-container">
<div class="skillbar-bar"></div>
</div>
<div class="skillbar-percent"></div>
</div>
<h3>Html/Css</h3>
<div class="skillbar" data-percent="90%">
<div class="skillbar-container">
<div class="skillbar-bar"></div>
</div>
<div class="skillbar-percent"></div>
</div>
<h3>JavaScript</h3>
<div class="skillbar" data-percent="69%">
<div class="skillbar-container">
<div class="skillbar-bar"></div>
</div>
<div class="skillbar-percent"></div>
</div>
<h3>Wordpress</h3>
<div class="skillbar" data-percent="92%">
<div class="skillbar-container">
<div class="skillbar-bar"></div>
</div>
<div class="skillbar-percent"></div>
</div>
<h3>Wordpress</h3>
<div class="skillbar" data-percent="100%">
<div class="skillbar-container">
<div class="skillbar-bar"></div>
</div>
<div class="skillbar-percent"></div>
</div>
SCSS
.skillbar {
position: relative;
display: block;
margin-bottom: 38px;
width: 100%;
border: 1px solid #dddddd;
height: 9px;
background: #fff;
&.active .skillbar-container {
width: 100%;
}
&-bar {
background: #009dda;
position: relative;
height: 100%;
box-sizing: border-box;
}
&-container {
height: 9px;
position: relative;
padding: 0px;
box-sizing: border-box;
width: 0;
transition: width 1.5s ease;
}
&-percent {
position: absolute;
right: -1px;
top: -46px;
font-size: 13px;
height: 35px;
line-height: 35px;
color: #000;
font-weight: bold;
}
}
JavaScript
jQuery.fn.extend({
onAppearanceApply: function( f ) {
var $window = $( window ),
window_height = $window.height(),
array_of_$elements = [];
this.each(function(i,el) {
array_of_$elements.push($( el ));
})
scrollHandler();
if (array_of_$elements.length) {
$window.on('resize', resizeHandler).on('resize', scrollHandler).on('scroll', scrollHandler);
}
function resizeHandler() {
window_height = $window.height();
}
function watchProcessedElements(array_of_indexes) {
var l, i;
for (l = array_of_indexes.length, i = l - 1; i > -1; --i) {
array_of_$elements.splice(array_of_indexes[i], 1);
}
if (!array_of_$elements.length) {
$window.off('resize', resizeHandler).off('scroll', scrollHandler).off('resize', scrollHandler);
}
}
function scrollHandler() {
var i, l, processed = [];
for ( l = array_of_$elements.length, i = 0; i < l; ++i ) {
if ($window.scrollTop() + window_height > array_of_$elements[i].offset().top) {
f.call( array_of_$elements[i] );
processed.push(i);
}
}
if (processed.length) {
watchProcessedElements(processed);
}
}
return this;
}
})
var color_options = {
luminosity: 'bright'
};
$('.skillbar').onAppearanceApply( animate );
function animate() {
var percent = parseInt( this.data('percent') ),
transition_element = this.find('.skillbar-container'),
span = this.find('.skillbar-percent');
this.find('.skillbar-bar').css({
width: percent + '%',
'background-color': randomColor(color_options)
});
$({ value: 0 }).animate({ value: percent }, {
duration: parseFloat( transition_element.css('transition-duration') ) * 1000,
easing: transition_element.css('transition-easing'),
step: function(val) {
span.text( ~~val + '%' );
}
})
this.addClass('active');
}