Home > database >  dynamically setting keyframes stroke-dashoffset
dynamically setting keyframes stroke-dashoffset

Time:07-07

Hi I am trying to create a circular percentage bar, it works with hard set values however it needs to be dynamically set, i assumed that i could set the styling properties in my script but im not sure how to access it.

html for percentage circle:

  <div >
            <div >
                    <div >
                            <div id="number">
                            </div>
                    </div>
            </div>

            <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="160px" height="160px">
                    <defs>
                            <linearGradient id="GradientColor">
                                    <stop offset="0%" stop-color="#e91e63" />
                                    <stop offset="100%" stop-color="#673ab7" />
                            </linearGradient>
                    </defs>
                    <circle cx="80" cy="80" r="70" stroke-linecap="round" />
            </svg>
            </div>

heres my keyframes styling:

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

css class styling:

.OuterCircle {
width: 120px;
height:120px;
border-radius:50%;
padding: 20px;
box-shadow: 6px 6px 10px -1px rgba(0,0,0,0.15),
           -6px -6px 10px -1px rgba(255,255,255,0.7);}


.InnerCircle {
width: 120px;
height: 120px;
border-radius:50%;
display: flex;
justify-content: center;
align-items: center;
box-shadow: inset 4px 4px 6px -1px rgba(0,0,0,0.2),
               -4px -4px 6px -1px rgba(255,255,255,0.7),
               -0.5px -0.5px 0px rgba(255,255,255,1),
               0.5px 0.5px 0px rgba(0,0,0,0.15),
               0px 12px 10px -10px rgba(0,0,0,0.05);}

circle{
fill:none;
stroke: url(#GradientColor);
stroke-width: 20px;
stroke-dasharray: 472;
stroke-dashoffset: 472;
animation: anim 2s linear forwards;}

and heres my script:

<script>
    let number = document.getElementById("number");
    let counter = 0;
    val keyframe =document.getElementById("keyframes");
    keyframe.setStroke-offset(VARIABLE)
    setInterval(() => {
            if(counter == VARIABLE){
                    clearInterval
            } else {
            counter  = 1;
            number.innerHTML = counter   "%"
            }
    }, 20)

CodePudding user response:

AFTER QUESTION UPDATE:


You can not access keyframes in JavaScript but as per the updated HTML and CSS, we can have your functionality in below manner:

  • I have also updated some of the styles (positioning)

let number = document.getElementById("number");
let circle = document.getElementById("circle");
let counter = 0;
let maxCounter = 100;

const totalOffset = 472;
let currentOffset = totalOffset
const strokeDashoffsetSteps = totalOffset / maxCounter;

let interval = setInterval(() => {
  // update counter
  counter  = 1;
  // update currentOffset
  currentOffset -= strokeDashoffsetSteps
  if(counter === maxCounter){
    clearInterval(interval);
  }
  // update text
  number.innerHTML = counter   "%"; 
  // update dashOffset
  circle.style.strokeDashoffset = currentOffset;
}, 20);
.percentBox {
  position: relative;
}

svg {
  position: absolute;
  top: 0;
  left: 0;
}

.OuterCircle {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  padding: 20px;
  box-shadow: 6px 6px 10px -1px rgba(0, 0, 0, 0.15),
    -6px -6px 10px -1px rgba(255, 255, 255, 0.7);
}

.InnerCircle {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: inset 4px 4px 6px -1px rgba(0, 0, 0, 0.2),
    -4px -4px 6px -1px rgba(255, 255, 255, 0.7),
    -0.5px -0.5px 0px rgba(255, 255, 255, 1),
    0.5px 0.5px 0px rgba(0, 0, 0, 0.15),
    0px 12px 10px -10px rgba(0, 0, 0, 0.05);
}

circle {
  fill: none;
  stroke: url(#GradientColor);
  stroke-width: 20px;
  stroke-dasharray: 472;
  stroke-dashoffset: 472;
  animation: anim 2s linear forwards;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Circle Progress Bar</title>
</head>

<body>
  <div >
    <div >
      <div >
        <div id="number">
        </div>
      </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="160px" height="160px">
      <defs>
        <linearGradient id="GradientColor">
          <stop offset="0%" stop-color="#e91e63" />
          <stop offset="100%" stop-color="#673ab7" />
        </linearGradient>
      </defs>
      <circle id="circle" cx="80" cy="80" r="70" stroke-linecap="round" />
    </svg>
  </div>
</body>

</html>

BEFORE QUESTION UPDATE:


You can not access keyframes in JavaScript but you can read your CSS file and parse your keyframes to get the actual data in JS or you can write the whole logic JS and I guess that'd be easy.

You can access strokeDashoffset using element.style.strokeDashoffset easily. Please execute the below example for the same.

const progress = document.querySelector('.progress');
console.log(progress.style.strokeDashoffset);

let offset = 0;
let interval = setInterval(() => {
  if (offset === 300) {
    clearInterval(interval);
  }
  progress.style.strokeDashoffset = offset  ;
}, 10);
.progress {
  padding: 10px;
  stroke: grey;
  stroke-width: 15px;
  stroke-dasharray: 10;
}
<svg >
  <path  d="m10,10 h300" />
</svg>

  • Related