JSFiddle - React, Tailwind, and code Playground

HTML

<h3>Думаю для портфолио будет норм</h3>
<button id="btn">Сюда вешаем любое событие</button>
<ul class="wrap">
	<li class="item">
		<h3>HTML+CSS</h3>
		<svg class="circles" viewBox="0 0 110 110">
			<circle r="45" cx="50%" cy="50%" fill="none" class="circle_first"></circle>
			<circle r="45" cx="50%" cy="50%" transform="rotate(-90 55 55)" class="circle__second circle-75"></circle>
		</svg>
		<span class="num">0%</span>
	</li>
	<li class="item">
		<h3>JS</h3>
		<svg class="circles" viewBox="0 0 110 110">
			<circle r="45" cx="50%" cy="50%" fill="none" class="circle_first"></circle>
			<circle r="45" cx="50%" cy="50%" transform="rotate(-90 55 55)" class="circle__second circle-47"></circle>
		</svg>
		<span class="num">0%</span>
	</li>
	<li class="item">
		<h3>PHP</h3>
		<svg class="circles" viewBox="0 0 110 110">
			<circle r="45" cx="50%" cy="50%" fill="none" class="circle_first"></circle>
			<circle r="45" cx="50%" cy="50%" transform="rotate(-90 55 55)" class="circle__second circle-54"></circle>
		</svg>
		<span class="num">0%</span>
	</li>
</ul>

CSS

#btn,footer{display:block}footer{margin:100% auto 0;text-align:center;width:100%}body{background:rgba(130,130,200,.5)}#btn{width:300px;height:50px;background:#935;color:#fff;border:0;border-radius:100px;margin:3rem auto 0;font-size:1rem}#btn:hover{background:#333}#btn:active,#btn:focus{outline:0}#res{font-size:1rem;margin-top:2rem;-webkit-transform:rotate(15deg);transform:rotate(15deg)}.circles{fill:none;stroke-width:15}.circle_first{stroke:#dfdcd5}.circle__second{stroke:#1bb696;stroke-dasharray:.001 282.6}.item{display:inline-block;border:1px solid #ccc;width:120px;height:180px;position:relative;z-index:3}.num{position:absolute;top:calc(66% - 8px);left:calc(50% - 15px);font-family:sans-serif;color:#fff;z-index:1}.wrap{width:90%;margin:2rem auto}#res,h3{color:#fff;font-family:sans-serif;text-align:center}

JavaScript

var start = document.getElementById('btn');

start.addEventListener("click", startAnimate);


function startAnimate () {
	var circles = document.querySelectorAll('.circles');
	var item = document.querySelectorAll('.item');
	var numArr = [];

	function takePercentage(str) {
		// Либо так:
		//console.log(str.slice(-2));
		//return str.slice(-2);
		//Либо так:
		let s = str.split("circle-")
		//console.log(s[1]);
		return s[1];
	}

	function runNum(el, stopNum, speed) {
		let timerId = setInterval(function(){

			let s = el.lastElementChild.textContent;		
			s = s.substring(0, s.length - 1);
			s++;
			el.lastElementChild.innerHTML = s + "%";
			if(el.lastElementChild.textContent == stopNum + "%"){
				clearInterval(timerId);
			}

		}, speed);
	}

	for(let i = 0; i < circles.length; i++) {
		numArr.push(takePercentage(circles[i].lastElementChild.getAttribute('class')));
	}

	runNum(item[0], numArr[0], 50);
	runNum(item[1], numArr[1], 100);
	runNum(item[2], numArr[2], 150);

	/*Анимация кругов*/
	var oneCircle = document.querySelector(".circles .circle-75");
	var twoCircle = document.querySelector(".circles .circle-47");
	var threeCircle = document.querySelector(".circles .circle-54");

	aggregate(oneCircle, 217, 18);
	aggregate(twoCircle, 132, 30);
	aggregate(threeCircle, 157, 50);
	
	function aggregate(el, stopNum, speed) {
		let timerId = setInterval(function(){
			
			let styleArr = getComputedStyle(el);
			let firstVal = styleArr.strokeDasharray.split(" ");
			firstVal[0] = firstVal[0].substring(0, firstVal[0].length - 3);
			el.style.strokeDasharray = Math.floor(firstVal[0]) + 1 + ", 282.6";

			if(el.style.strokeDasharray == stopNum + ", 282.6"){
				clearInterval(timerId);
			}

		}, speed);
	}

}