How can I make continuous animation attached to an svg inside a button on hover smooth?

I am working on a codewars link (a div). I would like the svg inside the div to rotate continuously on hover. The resulting hover effect is far from smooth, the svg jumps when the mouse rolls over it. The mouseout event is commented out because it makes it worth. What is the best way to optimize this? Codepen: https://codepen.io/forTheLoveOfCode/pen/MOvRNb

CSS:

#codewars-butn{
  position: absolute;
  top: 20%;
  left: 20%;
  background-color: #B21C15;
  border: 2px solid;
  border-radius: 10px;
}
body{
  background-color: #3F2740;
}
.codewars{
  display: inline-block;
  stroke:#000;
  stroke-dasharray: 1 5;
}

HTML:

<body>
  <div id="codewars-butn">
    <svg class="codewars" width="100" height="100">
      <defs>
          <path id="curve" d="M50 50 A 20 20 0 1 0 80 70" stroke-width="10" stroke-linecap="round" fill="none"/>
      </defs>
      <use href="#curve"/>
      <use href="#curve" transform="rotate(60, 50, 50)"/>
      <use href="#curve" transform="rotate(120, 50, 50)"/>
      <use href="#curve" transform="rotate(180, 50, 50)"/>
      <use href="#curve" transform="rotate(240, 50, 50)"/>
      <use href="#curve" transform="rotate(300, 50, 50)"/>

      <animateTransform attributeName="transform"
                              attributeType="XML"
                              type="rotate"
                              from="0 0 0"
                              to="360 0 0"
                              dur="5s"
                              begin="mouseover" 
<!--                               end="mouseout" -->
                              repeatCount="indefinite"/>
    </svg>
  </div>
</body>

Answers:

Answer

Here, I deleted svg transformation and made CSS only solution.

#codewars-butn:hover svg{
  animation-name: rotate;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

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

https://codepen.io/mnikolaus/pen/VrzJLY

Answer

Your problem is that you are starting the animation when the mouse is "over" the SVG. However what's happening is that when the SVG rotates, the paths are passing under the mouse pointer, and so a mouseout event is being fired, then another mouseover once the path has gone past.

The solution is to prevent the <path> elements from triggering mouse events. The way to do that is to add the following to your path.

pointer-events="none"

#codewars-butn{
  position: absolute;
  top: 20%;
  left: 20%;
  background-color: #B21C15;
  border: 2px solid;
  border-radius: 10px;
}
body{
  background-color: #3F2740;
}
.codewars{
  display: inline-block;
  stroke:#000;
  stroke-dasharray: 1 5;
}
  <div id="codewars-butn">
    <svg class="codewars" width="100" height="100">
      <defs>
          <path id="curve" d="M50 50 A 20 20 0 1 0 80 70" stroke-width="10"
                stroke-linecap="round" fill="none" pointer-events="none"/>
      </defs>
      <use href="#curve"/>
      <use href="#curve" transform="rotate(60, 50, 50)"/>
      <use href="#curve" transform="rotate(120, 50, 50)"/>
      <use href="#curve" transform="rotate(180, 50, 50)"/>
      <use href="#curve" transform="rotate(240, 50, 50)"/>
      <use href="#curve" transform="rotate(300, 50, 50)"/>

      <animateTransform attributeName="transform"
                              attributeType="XML"
                              type="rotate"
                              from="0 0 0"
                              to="360 0 0"
                              dur="5s"
                              begin="mouseover" 
                              repeatCount="indefinite"/>
    </svg>
  </div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.