Animating skill bars as you scroll down the page

How can I achieve a skill bar animation on a specific section of the page scroll? I have attempted to create a sliding skill bar animation, but it is not producing the desired effect. It currently starts animating at the beginning of the page, but I want it to start animating when scrolling to a specific section of the page.

In the code below, I am trying to initiate the animation on the scroll of third-sec. However, this is not happening as expected. Please help me fix the code by providing a snippet with the corrected code.

HTML

<section id="first-sec"></section>
<section id="second-sec"></section>
<section id="third-sec">

  <div class="container">
    <!-- First bar -->
    <div class="progress-bar" data-percentage="95%">
      <h4 class="progress-title-holder">
        <span class="progress-title">HTML5</span>
         <span class="progress-number-wrapper">
      <span class="progress-number-mark">
        <span class="percent"></span>
         <span class="down-arrow"></span>
        </span>
        </span>
        </h4>
      <div class="progress-content-outter">
        <div class="progress-content"></div>
      </div>
    </div>
    <!-- Second bar -->
    <div class="progress-bar" data-percentage="90%">
      <h4 class="progress-title-holder clearfix">
            <span class="progress-title">CSS3</span>
                <span class="progress-number-wrapper">
      <span class="progress-number-mark">
        <span class="percent"></span>
            <span class="down-arrow"></span>
                </span>
                </span>
                </h4>
      <div class="progress-content-outter">
        <div class="progress-content"></div>
      </div>
    </div>

CSS

body{
  margin:0;
}

#first-sec {
  height:100vh;
  background-color:#283c86;
}

#second-sec {
  height:100vh;
  background-color:#45a247;}

#third-sec {

}

/*====Skill Bar=====*/

.container {
    height: 300px;
    max-width: 100%;
  width:70%;
  margin: 10% auto;
}

.progress-bar {
    margin: 20px 0 10px;
    overflow: hidden;
    /*padding-left:20px;
  padding-right: 25px; /* Separate bars from container */
}

.progress-title-holder {
    padding-bottom: 7px;
    position: relative;
    margin: 5px 0;
    font-family: Montserrat, sans-serif;
    font-size: 2e;
    line-height: 15px;
    font-weight: 400;
    color: #2e2e2e;
}

.progress-title {
    z-index: 100;
    font-weight: bold;
}

.progress-number-wrapper {
    width: 100%;
    z-index: 10;
}

.progress-number-mark {
    margin-bottom: 4px;
    border-radius: 3px;
    background-color: #00d2ff;
    padding: 0 8px;
    position: absolute;
    bottom: 0;
    -moz-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
}

.progress-number-wrapper,
.progress-number-mark {
    font-family: Open Sans, sans-serif;
    font-size: 11px;
    line-height: 24px;
    height: 24px;
    letter-spacing: 0px;
    font-weight: 600;
    font-style: normal;
    text-transform: none;
    color: #ffffff;
}

.down-arrow {
    border-left: 3px solid transparent;
    border-right: 3px solid transparent;
    border-top: 3px solid #00d2ff;
    position: absolute;
    left: 50%;
    top: 100%;
    -moz-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
}

.progress-content-outter {
    height: 12px;
    background-color: #E1E1E0;
}

.progress-content {
    height: 21px;
    background-color: #00d2ff;
    width: 0%;
}

JQUERY

// Skill Bar Animation

jQuery(document).ready(function() {
  jQuery(".progress-bar").each(function() {
    jQuery(this).find(".progress-content").animate(
      {
        width: jQuery(this).attr("data-percentage")
      },
      2000
    );

    jQuery(this).find(".progress-number-mark").animate(
      {
        left: jQuery(this).attr("data-percentage")
      },
      {
        duration: 2000,
        step: function(now, fx) {
          var data = Math.round(now);
          jQuery(this).find(".percent").html(data + "%");
        }
      }
    );
  });
});

Answer №1

Is the layout going to remain consistent like this? The most efficient method would involve comparing the scrollTop() value while scrolling and triggering the animation when the third section is close to being visible.

UPDATE: You can also add an offset to the if condition to adjust the number of pixels that need to be scrolled in order to trigger the animation.

Check out this working fiddle:

jQuery(document).ready(function() {
/*MODIFICATION START*/
  jQuery(document).on('scroll', function(){
    if(jQuery('html,body').scrollTop() > jQuery('#first-sec').height()){
/*MODIFICATION END*/
      jQuery(".progress-bar").each(function() {
        jQuery(this).find(".progress-content").animate({
          width: jQuery(this).attr("data-percentage")
        },2000);

        jQuery(this).find(".progress-number-mark").animate({
          left: jQuery(this).attr("data-percentage")
        },{
          duration: 2000,
          step: function(now, fx) {
            var data = Math.round(now);
            jQuery(this).find(".percent").html(data + "%");
          }
        });
      });
/*MODIFICATION START*/
    }
  });
/*MODIFICATION END*/
});
body{
  margin:0;
}

#first-sec {
  height:100vh;
  background-color:#283c86;
}

#second-sec {
  height:100vh;
  background-color:#45a247;}

#third-sec {

}

/*====Skill Bar=====*/

.container {
    height: 300px;
    max-width: 100%;
  width:70%;
  margin: 10% auto;
}

.progress-bar {
    margin: 20px 0 10px;
    overflow: hidden;
    /*padding-left:20px;
  padding-right: 25px; /* Separate bars from container */
}

.progress-title-holder {
    padding-bottom: 7px;
    position: relative;
    margin: 5px 0;
    font-family: Montserrat, sans-serif;
    font-size: 2e;
    line-height: 15px;
    font-weight: 400;
    color: #2e2e2e;
}

.progress-title {
    z-index: 100;
    font-weight: bold;
}

.progress-number-wrapper {
    width: 100%;
    z-index: 10;
}

.progress-number-mark {
    margin-bottom: 4px;
    border-radius: 3px;
    background-color: #00d2ff;
    padding: 0 8px;
    position: absolute;
    bottom: 0;
    -moz-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
}

.progress-number-wrapper,
.progress-number-mark {
    font-family: Open Sans, sans-serif;
    font-size: 11px;
    line-height: 24px;
    height: 24px;
    letter-spacing: 0px;
    font-weight: 600;
    font-style: normal;
    text-transform: none;
    color: #ffffff;
}

.down-arrow {
    border-left: 3px solid transparent;
    border-right: 3px solid transparent;
    border-top: 3px solid #00d2ff;
    position: absolute;
    left: 50%;
    top: 100%;
    -moz-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
}

.progress-content-outter {
    height: 12px;
    background-color: #E1E1E0;
}

.progress-content {
    height: 21px;
    background-color: #00d2ff;
    width: 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="first-sec"></section>
<section id="second-sec"></section>
<section id="third-sec">

  <div class="container">
    <!-- First bar -->
    <div class="progress-bar" data-percentage="95%">
      <h4 class="progress-title-holder">
        <span class="progress-title">HTML5</span>
         <span class="progress-number-wrapper">
      <span class="progress-number-mark">
        <span class="percent"></span>
         <span class="down-arrow"></span>
        </span>
        </span>
        </h4>
      <div class="progress-content-outter">
        <div class="progress-content"></div>
      </div>
    </div>
    <!-- Second bar -->
    <div class="progress-bar" data-percentage="90%">
      <h4 class="progress-title-holder clearfix">
            <span class="progress-title">CSS3</span>
                <span class="progress-number-wrapper">
      <span class="progress-number-mark">
        <span class="percent"></span>
            <span class="down-arrow"></span>
                </span>
                </span>
                </h4>
      <div class="progress-content-outter">
        <div class="progress-content"></div>
      </div>
    </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The jQuery slider's next button is not functioning as intended

jQuery('#slider-container').bjqs({ 'animation' : 'slide', 'width' : 1060, 'height' : 500, 'showControls' : false, 'centerMarkers' : false, animationDuration: 500, rotationS ...

Tracing the variable passed by Jquery (AJAX) within the PHP code on the server to identify and

My web-hosted server has a PHP file in a specific folder. I want to send data from an HTML form using Jquery AJAX and view those variables in the PHP code on the server side. Here is my Jquery AJAX code: function sendtoServer() { $.ajax({ ur ...

Customize the inline click event using jQuery

I have a navigation with links that resemble the following: <a id="navform" href="#" tabindex="-1" onclick="mojarra.ab(this,event,'action','@form','content');return false" class=" ...

Unable to showcase information in a jQuery UI popup through AJAX when initially presented

I'm trying to display reviews from my database on a jQuery UI dialog box upon loading, but nothing is showing up. Here are the reviews: {"results":[{"review_text":"good"},{"review_text":"not bad"},{"review_text":"great"}]} Can someone please check m ...

Creating CSS Effects for Text Hover and Transition

Looking for help to implement the hover effect 4 on the following site: . I was able to create a test on JSFiddle, check it out here: https://jsfiddle.net/34aaqh70/ Struggling to make it auto-responsive, any tips would be appreciated. If there's a ...

Position the form / delete button in alignment with the rest of the buttons

I have a table with options at the end like View, Edit, and Delete. I need the Delete button to be inside a form so that I can POST the delete request. However, my button/form is not aligning on the same line as expected. I have tried using the form-inlin ...

The link-dark bootstrap class fails to have an impact

As a beginner in using bootstrap, I am creating my first simple website. However, I am facing an issue with the footer copyright section where the class "link-dark" is not taking effect. <!-- Copyright --> <div class="container-fluid ...

A missing semicolon is encountered while compiling a React application

I am currently working on my app using Create React App and incorporating scss. I have used a vscode plugin to convert the scss to css, but I keep encountering an error when running npm run build. The error message reads as follows: [email protected ...

Trouble displaying AngularJS $scope.data in the HTML code

I'm experiencing an issue where the data received from a POST request is being logged in the console, but is not displaying on the HTML page. Despite having a controller set up, the {{user}} variable is not appearing on the HTML page. While I can se ...

What is the process for incorporating data- attributes into ExtJs-generated HTML?

Currently working with ExtJs 4.1. In the process of developing a panel (for instance), I want to incorporate one or more "data-" attributes in the generated html, such as data-intro="some text" data-step="1" Any tips on how to achieve this? ...

Is it possible with jQuery UI Autocomplete to load search results into a designated div?

Currently in the process of switching from YUI to jQuery, I'm facing a challenge in loading autocomplete results into a specified container like a div. My goal is to dynamically populate a div with styled search results, which may include images asso ...

Looking to create an anchor tag that navigates to a specific ID on the page while accommodating a fixed header placement

In my application, the homepage's carousel displays multiple images with dynamically generated anchor tags that link to different routes. When clicking on the anchor tag, the page scrolls to the linked image but is obstructed by a fixed header. I want ...

Steps to enable navigation to external pages from a ReactJS app

I am working on a simple ReactJS application: [Demo] [Source] I am trying to implement navigation within the app from external sources without refreshing the web page. This functionality should be similar to using this.props.history.push(...). /public/i ...

Position the image at the center above the text

I am trying to position multiple images side by side, with each image having a date displayed beneath it. The challenge I am facing is that the length of the date extends beyond the width of the image, and I would like to center the image on top of its c ...

Infinite scrolling feature on Kendo UI mobile listview showcasing a single item at a time

Currently, I am utilizing the kendo ui mobile listview and encountering an issue when setting endlessScroll or loadMore to true. The problem arises as the listview only displays the first item in such instances. Upon inspecting with Chrome inspector, I ob ...

It is not possible to dynamically change the value of a checkbox using jQuery when it is checked or

When the checkbox value is changed to 1, it cannot be changed back to 0 when unchecked. $('.ChkBox').change(function() { if ($(this).attr('checked')) { $(this).val('1'); } else { $(this).val('0'); } ...

Confirming the truthfulness of a function while inside the execution of an asynchronous function

After submitting a form, I receive JSON as a response. My objective is to only submit the form if the received json.ok value is true. $("form").submit(function() { var _this = $(this); // send request to server, validate json, if ok return true $.getJSON( ...

When generating a docx file with html-docx-js, it lacks the capability to incorporate external CSS class styles into the document

I have been utilizing the html-docx-js module to convert html content into docx format. However, I am facing an issue where most of my CSS is externally loaded and html-docx-js does not apply any styles. Here is a simplified code sample: const html = &ap ...

Leveraging JavaScript to generate a downloadable PDF document from the existing webpage

My goal is to have the user click a button labeled 'View PDF' or 'Download PDF' on the current webpage. This button would then execute JavaScript code to generate a PDF based on how the current page appears. I attempted using jspdf for ...

Using JavaScript to empty input field when switching focus between input fields

I am experiencing an issue with clearing a input number field. Here is the code snippet in question: <input class="quantity_container" v-model="length.quantity" type="number" pattern="[0-9]*" inputmode="numeric" onfocus="if (this.value == &ap ...