Is there a way to incorporate an animated element within the track of my circular progress bar?

My circular progress bar features two paths, with one path increasing in length as data is received, eventually turning the entire circle red.

Here is the SVG HTML code:

<path d="M 50,50 m 0,-47 a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,-94" stroke="#A9B0B7" stroke-width="4" fill-opacity="0">
  </path>

  <path id="path2" d="M 50,50 m 0,-47 a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,-94" stroke="#EB483F" stroke-width="6" fill-opacity="0" style="stroke-dasharray: 295.416, 295.416; stroke-dashoffset: 250"></path>
  </svg>

The CSS code below enhances the loading of the red path:

#path2 {
  -webkit-transition-property: stroke-dashoffset;
  transition-property: stroke-dashoffset;
  -webkit-transition-duration: 1s;
  transition-duration: 0.3s;
}

.viewbox {
  width: 50%;
}

For more details and to view the code in action, visit this link.

I am looking to add an animation to the remaining gray portion, possibly with a small div moving through it to illuminate it. Something like what can be found in this example.

I believe I need to incorporate keyframe animation and place the div inside the svg path, but I am unsure of the exact method for achieving this.

Answer №1

For creating a pulsing animation on a circular progress bar, one approach is to design the pulse effect separately and then overlay it on the progress arc.

Begin by setting up a basic red progress bar with a growing animation.

.viewbox {
  width: 50%;
}

#progress {
  stroke-dasharray: 296 296;
  stroke-dashoffset: 296;
  animation: grow 5s ease-out infinite;
}

@keyframes grow {
  100% { stroke-dashoffset: 0; }
}
<svg class="viewbox" viewBox="0 0 100 100">

  <circle id="grey" cx="50" cy="50" r="47"
          transform="rotate(-90 50 50)"
          stroke="#A9B0B7" stroke-width="4" fill="none"/>
  
  <circle id="progress" cx="50" cy="50" r="47"
          transform="rotate(-90 50 50)" pointer-events="all"
          stroke="#EB483F" stroke-width="6" fill="none"/>
</svg>

Next, create the pulse animation to replicate a specific example provided.

.viewbox {
  width: 50%;
}

#pulse {
  stroke-dasharray: 0 0 0 296;
  animation: pulse 1.5s linear infinite;
}

@keyframes pulse {
   33% { stroke-dasharray: 0   0 148 296; }
   66% { stroke-dasharray: 0  50 200 296; }
  100% { stroke-dasharray: 0 296   0 296; }
}
<svg class="viewbox" viewBox="0 0 100 100">

  <rect width="100" height="100" fill="#EB483F"/>
  <circle id="pulse" cx="50" cy="50" r="47"
          transform="rotate(-90 50 50)" pointer-events="all"
          stroke="white" stroke-width="8" stroke-opacity="0.4" fill="none"/>
</svg>

To achieve the masking effect where black is transparent and white is opaque, modify the progress bar accordingly.

.viewbox {
  width: 50%;
}

#progress {
  stroke-dasharray: 296 296;
  stroke-dashoffset: 296;
  animation: grow 5s ease-out infinite;
}

@keyframes grow {
  100% { stroke-dashoffset: 0; }
}
<svg class="viewbox" viewBox="0 0 100 100">

  <rect width="100" height="100" fill="black"/>
  
  <circle id="progress" cx="50" cy="50" r="47"
          transform="rotate(-90 50 50)" pointer-events="all"
          stroke="white" stroke-width="6" fill="none"/>
</svg>

Bring everything together by creating a <mask> and applying it to the pulse animation.

.viewbox {
  width: 50%;
}

#progress {
  stroke-dasharray: 296 296;
  stroke-dashoffset: 296;
  animation: grow 5s ease-out infinite;
}

@keyframes grow {
  100% { stroke-dashoffset: 0; }
}

#pulse {
  stroke-dasharray: 0 0 0 296;
  animation: pulse 1.5s linear infinite;
}

@keyframes pulse {
   33% { stroke-dasharray: 0   0 148 296; }
   66% { stroke-dasharray: 0  50 200 296; }
  100% { stroke-dasharray: 0 296   0 296; }
}
<svg class="viewbox" viewBox="0 0 100 100">

  <defs>
    <mask id="progress-as-mask" >
      <rect width="100" height="100" fill="black"/>
      <circle id="progress" cx="50" cy="50" r="47"
              transform="rotate(-90 50 50)" pointer-events="all"
              stroke="white" stroke-width="6" fill="none"/>
    </mask>
  </defs>

  <circle id="grey" cx="50" cy="50" r="47"
          transform="rotate(-90 50 50)"
          stroke="#A9B0B7" stroke-width="4" fill="none"/>

  <g mask="url(#progress-as-mask)">
    <rect width="100" height="100" fill="#EB483F"/>
    <circle id="pulse" cx="50" cy="50" r="47"
            transform="rotate(-90 50 50)" pointer-events="all"
            stroke="white" stroke-width="8" stroke-opacity="0.4" fill="none"/>
  </g>
</svg>

If this guide isn't exactly what you're looking for, it should help point you in the right direction.

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

Having issues with CSS vertical margin not functioning properly

#outline { background: green; height: 96vh; width: 96vh; } #box { background: white; height: 86vh; width: 86vh; margin: 5vh; border: 1px solid #DDDDDD; overflow: hidden; } <div id="outlin ...

Testing with Phantom/Casper in a browser-based environment

Currently, I am utilizing Casper for UI testing on websites. My main concern is regarding the compatibility testing in various browsers such as IE, Chrome, and Firefox using Casper. If this cannot be achieved with Casper, I am open to alternative methods ...

Is it possible to incorporate npm modules into a browser and utilize them locally on a personal computer?

This is my first time working with npm modules and node.js, so I find it quite challenging. I have a JavaScript code with multiple data points and I need to find the closest city to each of them. In response to another question on Stack Overflow (Reverse ...

Troubleshooting an Issue with CSS Sliding Doors

I'm having trouble getting the right image to show on my website. The left side of the image is fine, but I can't figure out how to make the right one appear. As a HTML/CSS beginner, I'm still learning the basics. For more information, vis ...

Encountering a ReferenceError while attempting to implement logic on a newly created page

I've been experimenting with building a website using the Fresh framework. My goal was to add a simple drop-down feature for a button within a navigation bar, but I'm struggling to figure out where to place the necessary code. I attempted creatin ...

Exploring the intersection of JavaScript and PostgreSQL: Leveraging timezones and timestamps

I'm a bit confused about how to properly use timestamps. For example, when a user creates an article, they can choose a PublishDate, and the system also automatically stores a CreateDate. a. Should I make both PublishDate and CreateDate timestamps wi ...

Keyboard control of Material UI Checkbox

As we work on developing a web application using react and material ui, accessibility for persons with disabilities is a key consideration. This means ensuring that the web application is operable through keyboard navigation. It's important that user ...

Issues with broadcasting in React using Socket IO have arisen

Currently, I am developing a game using Socket IO where each room has its own channel of communication. The issue I am facing is that when a player places a bet, not only does the opponent receive the message, but the player themselves also receives it. B ...

What is the proper way to invoke a function in the code-behind using JavaScript?

I need to invoke a function in the code behind from JavaScript Button : <button class = "btn btn-outline btn-danger dim" type = "button" onclick = "confirmDelete ()"> <i class = "fa fa-trash"> </i> ...

Is there a way to achieve the same zooming and panning effects on an element using CSS transform instead of jQuery's

If you click on the following link, you will see a jsFiddle that I have created to demonstrate my question: http://jsfiddle.net/VbCcA/3/ In my project, I have developed a function that allows for panning and zooming to a specific element. This function i ...

Console frozen when executing an async JavaScript script to populate a Mongoose database

I'm currently delving into a personal project and aiming to unravel the intricate logic that is preventing my Node JS process from closing after executing populateTransactions(). My assumption is that the issue lies in not properly closing the DB con ...

Determining the size of the axis in correlation to a set constant length

Basic Concept I am currently developing a small tool designed to assist with geometric calculations for print-related items. Project Overview In this tool, users are asked to input the width and height of a box, represented visually as a CSS-based box, ...

The jQuery UI dialog box is malfunctioning and failing to return a value when the user clicks a button

I have a jQuery UI dialog box that I want to use for confirming a deletion action with the user. The issue I am facing is that the code below seems to return "True" or "False" immediately when the dialog pops up, even before the user has clicked the "Yes" ...

When scrolling, use the .scrollTop() function which includes a conditional statement that

As a newcomer to jQuery, I've been making progress but have hit a roadblock with this code: $(window).scroll(function(){ var $header = $('#header'); var $st = $(this).scrollTop(); console.log($st); if ($st < 250) { ...

Utilizing Async/Await with Node.js and Mongoose

Learning Promises and async/await programming is a new challenge for me, especially in the context of creating an API using Nodejs, Express, Mongoose, and MongoDB. While most tutorials focus on handling asynchronicity within a single file containing routin ...

Retrieve geographical coordinates from image metadata using JavaScript

Seeking help with extracting the GPS Exif tag from images using NodeJS. The data is currently structured as follows: { "gps": { "GPSTimeStamp": [2147483647, 76, 41], "GPSLongitude": [76, 41, 56.622], "GPSLatitude": [30, 43, 8 ...

displaying 'undefined' upon completion of iterating through a JSON file using $.each

For my project, I am attempting to extract only the date data from a JSON object. I have successfully looped through the object and displayed it, but the issue arises at the end of the loop where it shows undefined. I am not sure what mistake I am making. ...

Sorting through an array using a different array of values

Looking to filter one array with another, where values in the first array should match 'id' in the second array for filtering. The arrays in question are: const array1 = [a, b, c, d] The array to be filtered based on matching 'id' va ...

Swiper V7 React is experiencing issues with numerous parameters not functioning properly

Here is the code snippet I have been working on: I am currently exploring the Swiper library documentation to understand its functionalities better. import React from "react"; // Direct React component imports import { Swiper, SwiperSlide } fro ...

Searching for text in an HTML table using PHP DOM query

How do I extract text from HTML table cells using PHP DOM query? Here is a sample HTML table: <table> <tr> <th>Job Location:</th> <td><a href="/#">Kabul</a> </td> </tr> <tr> ...