<div class="uc-crug" data-percent="" data-duration="2300" data-color="#3a86ff" data-bg-color="#f0f0f000" data-width="3">
<svg viewBox="0 0 100 100">
<circle class="uc-crug-bg" cx="50" cy="50" r="45" />
<circle class="uc-crug-progress" cx="50" cy="50" r="45" />
</svg>
<div class="uc-crug-text"></div>
</div>
<style>
.uc-crug {
position: relative;
width: 280px;
height: 280px;
margin: 0 auto;
--progress-color: #3a86ff;
--bg-color: #f0f0f000;
--stroke-width: 3px;
}
.uc-crug svg {
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.uc-crug-bg {
fill: transparent;
stroke: var(--bg-color);
stroke-width: var(--stroke-width);
stroke-linecap: round;
}
.uc-crug-progress {
fill: transparent;
stroke: var(--progress-color);
stroke-width: var(--stroke-width);
stroke-linecap: round;
stroke-dasharray: 283;
stroke-dashoffset: 283;
transform-origin: 50% 50%;
}
/* .uc-crug-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: Arial, sans-serif;
font-size: 24px;
font-weight: bold;
color: #333;
}*/
.uc-crug-text {
display: none;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function() {
const circles = document.querySelectorAll('.uc-crug');
circles.forEach(container => {
const circle = container.querySelector('.uc-crug-progress');
const text = container.querySelector('.uc-crug-text');
const duration = parseInt(container.getAttribute('data-duration')) || 3000;
const targetPercent = parseInt(container.getAttribute('data-percent')) || 100;
const color = container.getAttribute('data-color') || '#3a86ff';
const bgColor = container.getAttribute('data-bg-color') || '#f0f0f0';
const strokeWidth = container.getAttribute('data-width') || '8';
// Устанавливаем кастомные свойства
container.style.setProperty('--progress-color', color);
container.style.setProperty('--bg-color', bgColor);
container.style.setProperty('--stroke-width', strokeWidth + 'px');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCircle(entry.target);
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
observer.observe(container);
function animateCircle(element) {
const circle = element.querySelector('.uc-crug-progress');
const text = element.querySelector('.uc-crug-text');
const percent = parseInt(element.getAttribute('data-percent')) || 100;
const duration = parseInt(element.getAttribute('data-duration')) || 3000;
const startTime = performance.now();
const circumference = 283;
const targetOffset = circumference - (percent / 100) * circumference;
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentOffset = circumference - (percent / 100) * circumference * progress;
circle.style.strokeDashoffset = currentOffset;
text.textContent = Math.round(percent * progress) + '%';
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
});
});
</script>