Animation on page load is executed a second time on mouse leave

我是研究僧i 提交于 2019-12-25 02:09:10

问题


I use an image and three spans as siblings within a wrapper (.avatar), to display a small avatar. I added two animations. The animated elements are the spans. They are animated with a small delay.

One animation is executed immediately (@keyframes rings-load). The other one (@keyframes rings-hover) executes, when .avatar is hovered.

Problem: After hovering .avatar, leaving the element, the initial animation is triggered a second time. Why is that? What would be considered best practice to prevent this behaviour?

Expected: Animation rings-load executes once on page load and is not executed again. Animation rings-hover executes once on every hover on element with class .avatar.

/* vars */

:root {
  --avatar-size: 140px;
}

/* general */

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  background: #333;
  margin: 0;
  padding: 0;
}

main {
  display: flex;
  flex-flow: column wrap;
  justify-content: center;
  align-content: center;
  height: 100vh;
}

/* avatar */

.avatar-container {
  margin: 2rem;
  padding: 21px;
}

.avatar img {
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 100%;
  padding: 2px;
  cursor: pointer;
}

.avatar span {
  border-radius: 100%;
  position: absolute;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border: 1px solid #ffffffee;
  background: #333;
  z-index: -1;
  opacity: 0;
  -webkit-transform: scale(1);
          transform: scale(1);
  -webkit-animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
          animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  -webkit-animation-iteration-count: 1;
          animation-iteration-count: 1;
}

.avatar span:nth-child(2) {
  -webkit-animation-delay: 200ms;
          animation-delay: 200ms;
}

.avatar span:nth-child(3) {
  -webkit-animation-delay: 300ms;
          animation-delay: 300ms;
}

.avatar:hover span {
  -webkit-animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
          animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
  -webkit-animation-iteration-count: 1;
          animation-iteration-count: 1;
}

.avatar:hover span:nth-child(2) {
  -webkit-animation-delay: 200ms;
          animation-delay: 200ms;
}

.avatar:hover span:nth-child(3) {
  -webkit-animation-delay: 300ms;
          animation-delay: 300ms;
}

/* animations */

@-webkit-keyframes rings-load {
  75% {
    opacity: 1;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  100% {
    opacity: 0;
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
}

@keyframes rings-load {
  75% {
    opacity: 1;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  100% {
    opacity: 0;
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
}

@-webkit-keyframes rings-hover {
  0% {
    opacity: 0;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  50% {
    opacity: 1;
  }
  75% {
    opacity: 0;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}

@keyframes rings-hover {
  0% {
    opacity: 0;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  50% {
    opacity: 1;
  }
  75% {
    opacity: 0;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}
<main>

  <div class="avatar-container">
    <div class="avatar">
      <span></span>
      <span></span>
      <span></span>
      <img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
    </div>
  </div>

</main>

回答1:


Your hover resets the base animation. Then, when you unhover, it is apllied again, so it plays again.

Instead, on hover add the new animation on top of the previous one. This will make the animation not to be reset, and the unhover won't trigger it

Alos, you can forget about webkit prefixes.

/* vars */

:root {
  --avatar-size: 140px;
}

/* general */

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  background: #333;
  margin: 0;
  padding: 0;
}

main {
  display: flex;
  flex-flow: column wrap;
  justify-content: center;
  align-content: center;
  height: 100vh;
}

/* avatar */

.avatar-container {
  margin: 2rem;
  padding: 21px;
}

.avatar img {
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 100%;
  padding: 2px;
  cursor: pointer;
}

.avatar span {
  border-radius: 100%;
  position: absolute;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border: 1px solid #ffffffee;
  background: #333;
  z-index: -1;
  opacity: 0;
  transform: scale(1);
  animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  animation-iteration-count: 1;
}

.avatar span:nth-child(2) {
          animation-delay: 200ms;
}

.avatar span:nth-child(3) {
          animation-delay: 300ms;
}

.avatar:hover span {
    animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
       rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 1;
}

.avatar:hover span:nth-child(2) {
          animation-delay: 200ms;
}

.avatar:hover span:nth-child(3) {
          animation-delay: 300ms;
}

/* animations */

@-webkit-keyframes rings-load {
  75% {
    opacity: 1;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  100% {
    opacity: 0;
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
}

@keyframes rings-load {
  75% {
    opacity: 1;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  100% {
    opacity: 0;
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
}

@-webkit-keyframes rings-hover {
  0% {
    opacity: 0;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  50% {
    opacity: 1;
  }
  75% {
    opacity: 0;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}

@keyframes rings-hover {
  0% {
    opacity: 0;
    -webkit-transform: scale(1.3);
            transform: scale(1.3);
  }
  50% {
    opacity: 1;
  }
  75% {
    opacity: 0;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}
<main>

  <div class="avatar-container">
    <div class="avatar">
      <span></span>
      <span></span>
      <span></span>
      <img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
    </div>
  </div>

</main>


来源:https://stackoverflow.com/questions/55004015/animation-on-page-load-is-executed-a-second-time-on-mouse-leave

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!