Как я могу сделать непрерывную анимацию, прикрепленную к svg внутри кнопки при наведении курсора?

1

Я работаю над ссылкой на codewars (div). Я хотел бы, чтобы svg внутри div вращался непрерывно при наведении. Получающийся эффект наведения далеко не гладкий, svg прыгает, когда мышь перекатывается над ним. Событие mouseout закомментировано, потому что оно стоит того. Как лучше всего это оптимизировать? 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>
Теги:
svg
animation
transform

2 ответа

2

Ваша проблема в том, что вы начинаете анимацию, когда мышь "перегружена" SVG. Однако, что происходит, когда SVG вращается, пути проходят под указателем мыши, и поэтому происходит событие mouseout, а затем другое наведение мыши после того, как путь прошел.

Решение состоит в том, чтобы предотвратить появление элементов <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>
  • 0
    спасибо, я попробую это! Отличное объяснение указателей-событий.
  • 1
    Чтобы избежать рывков при повторном наведении курсора, вы можете добавить restart="whenNotActive" jsfiddle.net/mwwdwqab
2

Здесь я удалил преобразование svg и сделал только решение CSS.

#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

  • 0
    Отличная идея @Mario Nikolaus, но если продолжительность анимации: 0,5 с, она все равно прыгает при наведении курсора мыши. Спасибо за ваш ответ, хотя!
  • 0
    Я не совсем уверен, что понимаю ваше определение « прыжков до сих пор» . Я думаю, что это просто вопрос настройки сейчас. Можешь объяснить больше? и я обновил код на codepen, чтобы повернуть только 60 градусов за анимацию

Ещё вопросы

Сообщество Overcoder
Наверх
Меню