Home > Enterprise >  Creating a infinite forward SVG animation with CSS and JavaScript
Creating a infinite forward SVG animation with CSS and JavaScript

Time:10-08

I want to create a spin load component that infinitely loops adding more dashoffset to the stroke

Here is a example:

const spinLoad = setInterval(() => {
  const loading = document.querySelector('#loading')
  loading.style.strokeDashoffset = `${Number(loading.style.strokeDashoffset)   800}`
}, 1000)
#loading {
  width: 100px;
  overflow: visible;
  position: absolute;
  z-index: 2;
  fill: transparent;
  stroke: #f1f1f1;
  stroke-width: 0.5rem;
  stroke-dasharray: 130px;
  stroke-dashoffset: 0;
  transition: ease-in-out 1s;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
  filter: drop-shadow(0px 3px 2px rgba(0, 0, 0, 0.6));
}
<svg id="loading" viewBox="0 0 240 240" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="icon" d="M42.3975 90C72.7709 37.3917 87.9576 11.0876 108.479 3.61845C121.734 -1.20615 136.266 -1.20615 149.521 3.61845C170.042 11.0876 185.229 37.3917 215.603 90C245.976 142.608 261.163 168.912 257.37 190.419C254.921 204.311 247.655 216.895 236.849 225.963C220.12 240 189.747 240 129 240C68.2532 240 37.8798 240 21.1507 225.963C10.3448 216.895 3.07901 204.311 0.629501 190.419C-3.16266 168.912 12.024 142.608 42.3975 90Z" />
</svg>

But this have three problems:

  1. It takes too much long for start spinning
  2. It spin at different speed sometimes, like lagging when go to other tab
  3. Sometimes happens a bug and the speed go CRAZY

Anyone knows how to build this spinning load? I would be very thankful :D

CodePudding user response:

When doing animations it's much better to use requestAnimationFrame to control it. In this case it's best to remove the css transition because adding two different ways of animating the same thing causes chaos. Then just keep adding to the dash-offset in the frame function.

const loading = document.querySelector('#loading')

let loadingAnimation;
    
const spinLoad = (time) => {
    const speed = 0.7 // lower number goes slower
    loading.style.strokeDashoffset = time * speed
    loadingAnimation = requestAnimationFrame(spinLoad)
}

loadingAnimation = requestAnimationFrame(spinLoad);
#loading {
    width: 100px;
    overflow: visible;
    position: absolute;
    z-index: 2;
    fill: transparent;
    stroke:#f1f1f1;
    stroke-width: 0.5rem;
    stroke-dasharray: 130px;
    stroke-dashoffset: 0;
    top: calc(50% - 50px);
    left: calc(50% - 50px);
    filter: drop-shadow(0px 3px 2px rgba(0, 0, 0, 0.6));
}
<svg
                        id="loading"
                        viewBox="0 0 240 240"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                    >
                        <path
                            id="icon"
                            d="M42.3975 90C72.7709 37.3917 87.9576 11.0876 108.479 3.61845C121.734 -1.20615 136.266 -1.20615 149.521 3.61845C170.042 11.0876 185.229 37.3917 215.603 90C245.976 142.608 261.163 168.912 257.37 190.419C254.921 204.311 247.655 216.895 236.849 225.963C220.12 240 189.747 240 129 240C68.2532 240 37.8798 240 21.1507 225.963C10.3448 216.895 3.07901 204.311 0.629501 190.419C-3.16266 168.912 12.024 142.608 42.3975 90Z"
                        />
                    </svg>

  • Related