reactjsanimationsvgrotationsvg-animate

Why is the SVG text not spins in place?


So I have this code:

#ring-svg {
  padding: 0;
  margin: 0;
  width: 100svw;
  height: 100svh;
  background-color: rgb(35, 35, 35);
}

.alt-font {
  font-family: "TnganAlt";
}

#textcircle {
  fill: rgb(35, 35, 35);
}

.textPath {
  fill: wheat;
}

#textcircle:hover+.text-circle-inside .textPath {
  fill: red;
  transition: fill 2s ease;
}

#textcircle:hover+.text-circle-inside {
  animation: spinText 10s linear infinite;
  transform-origin: center;
}

@keyframes spinText {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.zsap {
  display: flex;
  justify-content: center;
  align-items: center;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" id="ring-svg">
  <path id="textcircle" d="M250,400 a150,150 0 0,1 0,-350 a150,150 0 0,1 0,350 Z"/>
  <text font-family="Tngan" font-size="20" class="text-circle-inside">
    <textPath xlink:href="#textcircle" ariaLabel="CSS &amp; SVG are awesome" textLength="1090" class="textPath" transform="rotate(0)" startOffset="50%" text-anchor="middle">
    <tspan class="alt-font">&nbsp;»</tspan>AE5,Dx26Hw1E<tspan class="alt-font">j</tspan>^z<tspan class="alt-font">H</tspan>= AE5,DxxwP%1Ej^<tspan class="alt-font">«&nbsp;</tspan>AE5,Dx37zD1E<tspan class="alt-font">j</tspan>^z<tspan class="alt-font">H</tspan>= X#w6HktYAT`Bz7qpT1Ej^</textPath>
  </text>
</svg>

When you hover over the circle it should spin the text in place. It almost working but its start to go a little down and to the right.

Is it because the text is not a perfect circle from the start? or should I use different method the make it spin?


Solution

  • Often (specially when combining SVG presentation attributes and CSS -- and also in general) it is easier to place elements centered around 0,0. So, here I moved the path, so that the center is 0,0 and then use transform/translate to place the entire thing centered in the SVG.

    #ring-svg {
      padding: 0;
      margin: 0;
      width: 100svw;
      height: 100svh;
      background-color: rgb(35, 35, 35);
    }
    
    .alt-font {
      font-family: "TnganAlt";
    }
    
    #textcircle {
      fill: rgb(35, 35, 35);
    }
    
    .textPath {
      fill: wheat;
    }
    
    #textcircle:hover+.text-circle-inside .textPath {
      fill: red;
      transition: fill 2s ease;
    }
    
    #textcircle:hover+.text-circle-inside {
      animation: spinText 10s linear infinite;
    }
    
    @keyframes spinText {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
    
    .zsap {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" id="ring-svg">
      <g transform="translate(250 250)">
        <path id="textcircle" d="M 0 175 a 150 150 0 0 1 0 -350 a 150 150 0 0 1 0 350 Z" pathLength="500"/>
        <text font-family="Tngan" font-size="20" class="text-circle-inside">
          <textPath href="#textcircle" textLength="1090" class="textPath" startOffset="50%" text-anchor="middle">
          <tspan class="alt-font">&nbsp;»</tspan>AE5,Dx26Hw1E<tspan class="alt-font">j</tspan>^z<tspan class="alt-font">H</tspan>= AE5,DxxwP%1Ej^<tspan class="alt-font">«&nbsp;</tspan>AE5,Dx37zD1E<tspan class="alt-font">j</tspan>^z<tspan class="alt-font">H</tspan>= X#w6HktYAT`Bz7qpT1Ej^</textPath>
        </text>
      </g>
    </svg>