Javascript For SVG Animations To Create Stylish Progress Loaders
In this post I will provides a few examples of creating stylish progress loaders using Javascript for SVG animations.

In this post I will provides a few examples of creating stylish progress loaders using Javascript for SVG animations.

SVG Animations Using Javascript

SVG

SVGs ( Scalable Vector Graphics ) are vector images built on mathematical formulas to define shapes in an image. The important aspect of these images are that they can be scaled without losing image quality.

I use SVG Path Visualizer when I need to create a custom image using Paths. The webpage has a breakdown for each element with an explanation as well as samples if you are new to SVGs.

To implement these in HTML, you would use the <svg> tag and specify the viewport size. Inside the <svg> tag, you would add your SVG elements.

Some predefined elements are:

circledraw a circle
polygondraw a polygon shape
rectdraw a rectangle
linedraw a line
polylinedraw a series of jointed lines
pathcompletely customizable shape

Code

In this example code, I will show 4 examples of adding SVGs in an webpage including Javascript for SVG animations. The SVGs all will be used as progress loaders with a progress animation. The last example uses the <path> to create a dynamic image using Javascript.

General Page Setup

Basic page setup centering the main div wrapper.

Each SVG element is separated in their own div inside the main centered div.

.center onclick="startAnim()"start the Javascript function named startAnim() when the user clicks this div which is the main content wrapper.

Child Divs

the background SVGthe gray background mirroring the size and dimensions of the progress SVG
the progress SVGthis holds the value of the currently set progress for the SVG
H1displays the progress percent for each SVG progress loader
NOTE:

The key making the progress loader work with values 0% to 100% is to set the following two attributes accordingly.

pathLengthset to 100
stroke-dasharrayset the dash size - ex. 0, 100 is 0% and 22, 100 is 22%
<!DOCTYPE html>
<html>
<head>
<title>Javascript SVG Animations</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>

/* CSS styling here */

</style>
<script>

// Javascript content here
</script>
</head>
<body>
    <div class="center" onclick="startAnim()">
		<div>
			<h1 class="displayProgress">0%</h1>
			<svg viewbox="0 0 100 100" width="100%" class="circularProgress">
				<circle cx="50" cy="50" r="40" stroke="gray" stroke-width="3.5" fill="none"></circle>
				<circle class="progressTrack" cx="50" cy="50" r="40" pathLength="100" stroke-dasharray="0, 100" stroke-linecap="round" stroke="green" stroke-width="3" fill="none"></circle>
			</svg>
		</div>
		<div>
			<h1 class="displayProgress">0%</h1>
			<svg viewbox="0 0 100 100" width="100%"class="circularProgress">
				<rect width="50" height="50" x="25" y="25" rx="10" ry="10" stroke="gray" stroke-width="3" fill="none"></rect>
				<rect class="progressTrack" width="50" height="50" x="25" y="25" rx="10" ry="10" pathLength="100" stroke-dasharray="0, 100" stroke-linecap="round" stroke="green" stroke-width="3" fill="none"></rect>
				
			</svg>
		</div>
		<div>
			<h1 class="displayProgress">0%</h1>
			<svg viewbox="0 0 100 100" width="100%" class="circularProgress">
				<polygon points="50,10 90,90 10,90" stroke="gray" stroke-width="3" fill="none" />
				<polygon class="progressTrack"  points="50,10 90,90 10,90" pathLength="100" stroke-dasharray="0, 100" stroke-linecap="round" stroke="green" stroke-width="3" fill="none" />
			</svg>
			
		</div>
		<div>
			<h1 class="displayProgress">0%</h1>
			<svg viewbox="0 0 100 100" width="100%" class="circularProgress">
				<path id="animatedTrack" d="M10,50 S25,10 50,50 S75,90 90,50" stroke="gray" stroke-width="3" fill="none" />
				<path class="progressTrack"  d="M10,50 S25,10 50,50 S75,90 90,50" pathLength="100" stroke-dasharray="0, 100" stroke-linecap="round" stroke="green" stroke-width="3" fill="none" />
			</svg>
		</div>
	</div>
</body>
</html>

CSS

Page styling and main content div styling.

html {
	background-color: #004e5c;
}

body {
	color: whitesmoke;
  	background-color: #004e5c;
	display: grid;
	width: 100vw;
	height: 100vh;
	margin: auto;
	padding: 0;
}

.center {
	margin: auto;
}

Child Div Styling

.center div
displayflex display properties set for layout
flex-directioncolumn so they line in middle one below the next and so on
align-itemscentering the items
justify-contentcenter div
height25vh set because there are 4 child divs, wanted them to fit without scroll needed
.center div {
	display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
	height: 25vh;
}

Header For Progress Value

.center div h1
positionabsolute so the text can be positioned in center of SVG
text-shadowdecorate the text a little
.center div h1 {
	position: absolute;
}

.displayProgress {
	text-shadow: 2px 2px 4px black;
}

Apply Shadow To SVG

svg *
filteradd the drop-shadow image filter to SVG images
svg * {
	filter: drop-shadow(0px 0px 0.75px black);
}

Animated Path SVG

.progressTrack, #animatedTrack
transitionanimate the attribute changes to the SVGs with the id set to animatedTrack and class name of progressTrack. Animation duration set to 1 sec.
.progressTrack, #animatedTrack {
	filter: drop-shadow(0px 0px 0.75px whitesmoke); 
	transition: all 1s;
}

Javascript

Below is the Javascript used for applying new attributes to the elements, starting/stopping animation and generating random progresses.

progressarray holding the progress of each example SVG in the webpage
isAnimatingswitching boolean for starting and stopping the animation
startAnim()function to start/stop animation, updates the isAnimating switching boolean
startProgressAnim()function initiating the animation, contains a 2 sec loop to change until user click on wrapper div again to stop
randomColor()function to create a random color for each of the progress loaders
randomProgressValue()function to generate a random progress value to use in each progress loader. This is also called to change the path values of the last SVG.
let progress = [0,0,0,0];
var isAnimating = false;

function startAnim(){
	isAnimating = !isAnimating;
	if(isAnimating){
		setTimeout(startProgressAnim, 100);
	}
}

function startProgressAnim(){
	if(!isAnimating){
		return;
	}
	var elements = document.getElementsByClassName("progressTrack")
	var progressHeaders = document.getElementsByClassName("displayProgress");

	for(let i = 0; i < progress.length; i++){
		progress[i] = randomProgressValue();
		elements[i].setAttribute("stroke-dasharray", `${progress[i]}, 100`);
		elements[i].setAttribute("stroke", "#" + randomColor());
		
		progressHeaders[i].innerHTML = `${Math.floor(progress[i])}%`;

		if(i == progress.length-1){
			var c1 = randomProgressValue();
			var c2 = randomProgressValue();
			elements[i].setAttribute("d", `M10,50 S25,${c1} 50,50 S75,${c2} 90,50`);
			document.getElementById("animatedTrack").setAttribute("d", `M10,50 S25,${c1} 50,50 S75,${c2} 90,50`);
		}
	}
	
	setTimeout(startProgressAnim, 2000);
	
}

function randomColor(){
	return Math.floor(Math.random() * 0xffffff).toString(16);
}

function randomProgressValue(){
	return Math.floor(Math.random() * 100);
}

Hope this was useful.