I want to activate my progress bar on scroll and use waypoints.js
for that. However it's not working and the progress bar is either 'filled' before I scroll over or (like in my current code) remains 'empty' on scroll as well as on page load.
html:
<div id="progress-bar-start" class="center-block progress-wrapper">
<h4>UI/UX Design:</h4>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="max-width: 60%">
<span class="title">60%</span>
</div>
</div>
</div>
css:
#skills {
margin-top: 0px;
margin-bottom: 50px;
.skills-title::first-letter {
font-size: 60px;
color: pink;
}
.progress-wrapper {
width: 50%;
margin-top: 30px;
.progress-bar {
background-color: pink;
width: 0;
animation: progress 1.5s ease-in-out forwards;
.title {
opacity: 0;
animation: show 0.35s forwards ease-in-out 0.5s;
}
}
.progress {
height: 40px;
}
}
@keyframes show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
js:
$('#skills').waypoint(function(direction) {
if (direction === 'down') {
$('.progress-bar').addClass("show");
} else {
$('.progress-bar').removeClass("show");
}
}, {
offset: '50%'
});
There are a couple of things to note here.
offset
option: By default a waypoint triggers when the top of the element hits the top of the window. The offset
specifies the triggering distance between these top positions.
In your example it is important to note, that the #skills
section sticks to the top of the window, which means that with an offset >= 0
it triggers immediately at pageload, and only once (with 'down' direction).width
of the bar, as opposed to the visibility/display. Also, setting the width should be done via the width
instead of the max-width
attribute, as that is needed to run the css animation.So, the solution is as follows:
HTML
<div class="progress">
<!-- CHANGE style="max-width: 60%" TO data-score="60%" -->
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" data-score="60%"></div>
</div>
JS
$('#skills').waypoint(function(direction) {
if (direction === 'down') {
$('.progress-bar').width(function(){
// this here refers to individual .progress-bar items
return $(this).data('score');
});
} else {
$('.progress-bar').width(0);
}
}, { offset: '10%' });
SCSS
#skills {
margin-top: 100px;
/* …the rest is the same… */
}
Working example available on Fiddle as well.
UPDATE (answer for a comment):
In case you would like the animation to happen every time the user scrolls down, but do not show the decreasing animation of the progress bar in the meantime you can alter the code as follows:
$('#skills').waypoint(function(direction) {
if (direction === 'down') {
$('.progress-bar').width(function(){
// this here refers to individual .progress-bar items
return $(this).data('score');
});
}
}, { offset: '10%' });
$('#skills').waypoint(function(direction) {
if (direction === 'up') {
$('.progress-bar').width(0);
}
}, { offset: '100vh' });
The code above still runs the decrease animation, but when not running in an iframe (like in Fiddle) that wont be visible as it got triggered when the #skills
is out of the viewport. (In this case you might make use the visibility classes too.)
In order to better showcase the functionality, I have also set margin-top: 100vh;
on #skills
in this Fiddle version.