Animated SVG, circle stroke hover

10,642

If you're targeting somewhat modern browsers, I'd suggest using svg animations.

You can animate strokes by using a stroke-dasharray that has the length of your circle (2 * PI * r) and a dash offset of equal length. Play around with the animation values of your dash length and offset to create different effects.

Here's an example of how to do so.

.circle:hover {
  /* calculate using: (2 * PI * R) */
  stroke-dasharray: 227;
  stroke-dashoffset: 0;
  animation-iteration-count: infinite;
  animation-name: rotate;
  animation-duration: 2s;
  animation-direction: alternate;
  animation-timing-function: linear;
}

@keyframes rotate {
  to {
    stroke-dashoffset: 227;
  }
}
<svg id="right_arrow" class="direction__right direction__item" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
  <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28" />
  <circle cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="2" />
  <circle class="circle" cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="4" />
</svg>

Using the css animation property and @keyframes, you can do all kinds of fancy stuff. If you'd rather keep it simple, you could also try using the transition property, like in the example below. Note that I've used the svg transform attribute to change the starting point of the dashed stroke.

.another-circle {
  stroke-dasharray: 227;
  stroke-dashoffset: 227;
  transition: stroke-dashoffset 2s linear;
}
.another-circle:hover {
  stroke-dashoffset: 0;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
  <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28" />
  <circle cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="2" />
  <circle transform="rotate(-90 40 40)" class="another-circle" cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="4" />
</svg>

Share:
10,642
Neil
Author by

Neil

Updated on June 25, 2022

Comments

  • Neil
    Neil almost 2 years

    Looking to mimic the animated arrow:

    http://uve.info/

    On hover the stroke overlays the circle, I have the shape created in Illustrator, thats fine, positioning easy. just animating the stroke.

    HTML (Inline SVG):

    <svg id="right_arrow" class="direction__right direction__item" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
        <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28"/>
        <path class="arrow offset-colour" d="M40,1c21.5,0,39,17.5,39,39S61.5,79,40,79S1,61.5,1,40S18.5,1,40,1 M40,0C17.9,0,0,17.9,0,40s17.9,40,40,40s40-17.9,40-40S62.1,0,40,0L40,0z"/>
    </svg>
    

    The path, is a circle already. I want another path that sits on top of the current path to emulate the uve.info site. This whole animation is done via hover. This is what the arrow should look like mid animation proving a pain.

    uve.info arrow animation

    What would be the best way to invoke the stroke?

    Thanks all.

  • Neil
    Neil about 8 years
    Nice answer! I have used transform to bring the starting point to "deg", however is there anyway that we can reverse the animation when the hover state is not initiated? Ideally the stroke should only appear when hover starts.
  • user3297291
    user3297291 about 8 years
    Thanks. I've included another example that shows a slightly different example that reverses the animation by using a simple transition rather than an elaborate animation. I'm not sure how fancy you need it to be (i.e.: if you need to use animation).
  • Neil
    Neil about 8 years
    looks sweet, I love the effect when you come off the hover state. However I wanted understand your direction on using inline styles on the svg such as the transform rotate property (why 3 values). I also wanted to understand the correlation between the the stroke 227 value, and how you got to that number.
  • user3297291
    user3297291 about 8 years
    The inline svg transform can get a bit tricky, but in this case it's quite straight forward: the first value is the rotation in degrees, the second and third value represent the center of rotation (x and y). So, to start at the top of the circle, we rotate 90 degrees (360/4) counter clockwise. We want to rotate around the center of the circle (cx and cy), so those are the second and third values. 227 is just a bit more than the length of the stroke, and can be calculated using: 2 * PI * r, which in this case is 2 * 3.14 * 36 = 226.08
  • Neil
    Neil about 8 years
    That makes more sense. Personally could you achieve the same result to use transform-origin: 50%? Also if I plan to scale the circle vector so I have to change the 227 or can this remain an constant?
  • user3297291
    user3297291 about 8 years
    cx, cy, and r are relative to the viewBox. You can scale your <svg> using width and height without changing the viewBox; you won't have to update the circles center or stroke length. I don't think you can use css transforms on inner svg elements, but you'd have to check that in the specs.