点击后仅一次使一个div添加CSS弹跳动画

5
我有一个CSS地图标记,其中包含一些CSS3动画,下面是它的代码: https://jsfiddle.net/xg7xfzeq/
body {
  background: #e6e6e6;
}

.pin {
  width: 30px;
  height: 30px;
  border-radius: 50% 50% 50% 0;
  background: #00cae9;
  position: absolute;
  transform: rotate(-45deg);
  left: 50%;
  top: 50%;
  margin: -20px 0 0 -20px;
}
.pin:after {
  content: "";
  width: 14px;
  height: 14px;
  margin: 8px 0 0 8px;
  background: #e6e6e6;
  position: absolute;
  border-radius: 50%;
}

.bounce {
  animation-name: bounce;
  animation-fill-mode: both;
  animation-duration: 1s;
}

.pulse {
  background: #d6d4d4;
  border-radius: 50%;
  height: 14px;
  width: 14px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 11px 0px 0px -12px;
  transform: rotateX(55deg);
  z-index: -2;
}
.pulse:after {
  content: "";
  border-radius: 50%;
  height: 40px;
  width: 40px;
  position: absolute;
  margin: -13px 0 0 -13px;
  animation: pulsate 1s ease-out;
  animation-iteration-count: infinite;
  opacity: 0;
  box-shadow: 0 0 1px 2px #00cae9;
  animation-delay: 1.1s;
}

@keyframes pulsate {
  0% {
    transform: scale(0.1, 0.1);
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1.2, 1.2);
    opacity: 0;
  }
}

@keyframes bounce {
  0% {
    opacity: 0;
    transform: translateY(-2000px) rotate(-45deg);
  }

  60% {
    opacity: 1;
    transform: translateY(30px) rotate(-45deg);
  }

  80% {
    transform: translateY(-10px) rotate(-45deg);
  }

  100% {
    transform: translateY(0) rotate(-45deg);
  }
}
.myBounceDiv { 
        -moz-animation:bounce .40s linear;  
        -webkit-animation:bounce .40s linear; 
} 

@-moz-keyframes bounce {


 0%{ -moz-transform:scale(0); opacity:0;}
        50%{ -moz-transform:scale(1.3); opacity:0.4; }
        75%{ -moz-transform:scale(0.9); opacity:0.7;}
        100%{ -moz-transform:scale(1); opacity:1;}
}

@-webkit-keyframes bounce {
        0%{ -webkit-transform:scale(0); opacity:0;}
        50%{ -webkit-transform:scale(1.3); opacity:0.4;}
        75%{ -webkit-transform:scale(0.9); opacity:0.7;}
        100%{ -webkit-transform:scale(1); opacity:1;}
}

以及它的HTML

<div class='myBounceDiv'>
<div class='pin bounce'></div>
<div class='pulse'></div>
</div>

我想在点击时添加弹跳的CSS3动画,我找到了一些解决方案,例如使用JavaScript在单击其div时更改CSS样式。虽然这是可能的,但当我更改它的CSS类时,它将永久地开始弹跳。如何使它只播放一次动画?一种方法是触发计时器,在1000毫秒后将其CSS类更改为第一个类,但还有另一个问题,我的div的类有另一个动画(当它首次出现在页面上时,从顶部向下掉落),因此如果我将其CSS类更改为弹跳动画,然后再次更改回原始状态,外观动画会再次触发,这不是我需要的。 是否有任何使用纯JavaScript和CSS实现我所需的方式?实际上,我需要做类似于这样的东西http://dynamicsjs.com/examples/pin.html,但它的动画是在单击时使用CSS显示的。

2个回答

6
据我理解,您的意思是这样的:
  • 第一版本中,脉冲效果和弹跳效果只有在单击一次后才会运行。
  • 第二个版本中,脉冲效果始终像现在的版本一样运行,但弹跳效果只有在单击一次后才会运行。

第一个版本

element = document.getElementById("marker");

element.addEventListener("click", function(e) {
  e.preventDefault;
  
  // -> removing the class
  element.classList.remove("bounce");
  
  // -> triggering reflow /* The actual magic */
  // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered.
  element.offsetWidth = element.offsetWidth;
  
  // -> and re-adding the class
  element.classList.add("bounce");
}, false);
body {
  background: #e6e6e6;
}

.pin {
  width: 30px;
  height: 30px;
  border-radius: 50% 50% 50% 0;
  background: #00cae9;
  position: absolute;
  transform: rotate(-45deg);
  left: 50%;
  top: 50%;
  margin: -20px 0 0 -20px;
}
.pin:after {
  content: "";
  width: 14px;
  height: 14px;
  margin: 8px 0 0 8px;
  background: #e6e6e6;
  position: absolute;
  border-radius: 50%;
}

.bounce {
  animation-name: bounce;
  animation-fill-mode: both;
  animation-duration: 0.9s;
}

.pulse {
  background: #d6d4d4;
  border-radius: 50%;
  height: 14px;
  width: 14px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 11px 0px 0px -12px;
  transform: rotateX(55deg);
  z-index: -2;
}
.bounce+.pulse:after {
  content: "";
  border-radius: 50%;
  height: 40px;
  width: 40px;
  position: absolute;
  margin: -13px 0 0 -13px;
  animation: pulsate 1s ease-out;
  opacity: 0;
  box-shadow: 0 0 1px 2px #00cae9;
  animation-delay: 0.1s;  
  -webkit-animation-iteration-count: 1;
  animation-iteration-count: 1;
}

@keyframes pulsate {
  0%, 100% {
    transform: scale(0.1, 0.1);
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1.2, 1.2);
    opacity: 0;
  }
}

@keyframes bounce {
  0% {
    opacity: 0;
    transform: translateY(-1000px) rotate(-45deg);
  }

  60% {
    opacity: 1;
    transform: translateY(30px) rotate(-45deg);
  }

  80% {
    transform: translateY(-10px) rotate(-45deg);
  }

  100% {
    transform: translateY(0) rotate(-45deg);
  }
}
.myBounceDiv { 
        -moz-animation:bounce .40s linear;  
        -webkit-animation:bounce .40s linear; 
} 

@-moz-keyframes bounce {
        0%{ -moz-transform:scale(0); opacity:0;}
        50%{ -moz-transform:scale(1.3); opacity:0.4; }
        75%{ -moz-transform:scale(0.9); opacity:0.7;}
        100%{ -moz-transform:scale(1); opacity:1;}
}

@-webkit-keyframes bounce {
        0%{ -webkit-transform:scale(0); opacity:0;}
        50%{ -webkit-transform:scale(1.3); opacity:0.4;}
        75%{ -webkit-transform:scale(0.9); opacity:0.7;}
        100%{ -webkit-transform:scale(1); opacity:1;}
}
<div class='myBounceDiv'>
<div id="marker" class='pin'></div>
<div class='pulse'></div>
</div>

第二版

/*
  Reference: https://css-tricks.com/restart-css-animation/
*/

element = document.getElementById("marker");

element.addEventListener("click", function(e) {
  e.preventDefault;
  
  // -> removing the class
  element.classList.remove("bounce");
  
  // -> triggering reflow /* The actual magic */
  // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered.
  element.offsetWidth = element.offsetWidth;
  
  // -> and re-adding the class
  element.classList.add("bounce");
}, false);
body {
  background: #e6e6e6;
}

.pin {
  width: 30px;
  height: 30px;
  border-radius: 50% 50% 50% 0;
  background: #00cae9;
  position: absolute;
  transform: rotate(-45deg);
  left: 50%;
  top: 50%;
  margin: -20px 0 0 -20px;
}
.pin:after {
  content: "";
  width: 14px;
  height: 14px;
  margin: 8px 0 0 8px;
  background: #e6e6e6;
  position: absolute;
  border-radius: 50%;
}

.bounce {
  animation-name: bounce;
  animation-fill-mode: both;
  animation-duration: 0.9s;
}

.pulse {
  background: #d6d4d4;
  border-radius: 50%;
  height: 14px;
  width: 14px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 11px 0px 0px -12px;
  transform: rotateX(55deg);
  z-index: -2;
}
.pulse:after {
  content: "";
  border-radius: 50%;
  height: 40px;
  width: 40px;
  position: absolute;
  margin: -13px 0 0 -13px;
  animation: pulsate 1s ease-out;
  animation-iteration-count: infinite;
  opacity: 0;
  box-shadow: 0 0 1px 2px #00cae9;
  animation-delay: 0.1s;  
}

@keyframes pulsate {
  0%, 100% {
    transform: scale(0.1, 0.1);
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1.2, 1.2);
    opacity: 0;
  }
}

@keyframes bounce {
  0% {
    opacity: 0;
    transform: translateY(-1000px) rotate(-45deg);
  }

  60% {
    opacity: 1;
    transform: translateY(30px) rotate(-45deg);
  }

  80% {
    transform: translateY(-10px) rotate(-45deg);
  }

  100% {
    transform: translateY(0) rotate(-45deg);
  }
}
.myBounceDiv { 
        -moz-animation:bounce .40s linear;  
        -webkit-animation:bounce .40s linear; 
} 

@-moz-keyframes bounce {
        0%{ -moz-transform:scale(0); opacity:0;}
        50%{ -moz-transform:scale(1.3); opacity:0.4; }
        75%{ -moz-transform:scale(0.9); opacity:0.7;}
        100%{ -moz-transform:scale(1); opacity:1;}
}

@-webkit-keyframes bounce {
        0%{ -webkit-transform:scale(0); opacity:0;}
        50%{ -webkit-transform:scale(1.3); opacity:0.4;}
        75%{ -webkit-transform:scale(0.9); opacity:0.7;}
        100%{ -webkit-transform:scale(1); opacity:1;}
}
<div class='myBounceDiv'>
<div id="marker" class='pin'></div>
<div class='pulse'></div>
</div>

更新

/*
  Reference: https://css-tricks.com/restart-css-animation/
*/




element = document.getElementById("marker");


setTimeout(function() {
  element.classList.remove("bounce");
}, 1000);


element.addEventListener("click", function(e) {
  e.preventDefault;
  
  // -> removing the class
  element.classList.remove("drop");
  
  // -> triggering reflow /* The actual magic */
  // without this it wouldn't work. Try uncommenting the line and the transition won't be retriggered.
  element.offsetWidth = element.offsetWidth;
  
  // -> and re-adding the class
  element.classList.add("drop");
}, false);
body {
  background: #e6e6e6;
}

.pin {
  width: 30px;
  height: 30px;
  border-radius: 50% 50% 50% 0;
  background: #00cae9;
  position: absolute;
  transform: rotate(-45deg);
  left: 50%;
  top: 50%;
  margin: -20px 0 0 -20px;
}
.pin:after {
  content: "";
  width: 14px;
  height: 14px;
  margin: 8px 0 0 8px;
  background: #e6e6e6;
  position: absolute;
  border-radius: 50%;
}

.bounce {
  animation-name: bounce;
  animation-fill-mode: both;
  animation-duration: 0.9s;
}

.pulse {
  background: #d6d4d4;
  border-radius: 50%;
  height: 14px;
  width: 14px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 11px 0px 0px -12px;
  transform: rotateX(55deg);
  z-index: -2;
}
.pulse:after {
  content: "";
  border-radius: 50%;
  height: 40px;
  width: 40px;
  position: absolute;
  margin: -13px 0 0 -13px;
  animation: pulsate 1s ease-out;
  animation-iteration-count: infinite;
  opacity: 0;
  box-shadow: 0 0 1px 2px #00cae9;
  animation-delay: 0.1s;  
}

@keyframes pulsate {
  0%, 100% {
    transform: scale(0.1, 0.1);
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1.2, 1.2);
    opacity: 0;
  }
}

@keyframes bounce {
  0% {
    opacity: 0;
    transform: translateY(-1000px) rotate(-45deg);
  }

  60% {
    opacity: 1;
    transform: translateY(5px) rotate(-45deg);
  }

  80% {
    transform: translateY(-10px) rotate(-45deg);
  }

  100% {
    transform: translateY(0) rotate(-45deg);
  }
}
.myBounceDiv { 
        -moz-animation:bounce .40s linear;  
        -webkit-animation:bounce .40s linear; 
} 

@-moz-keyframes bounce {
        0%{ -moz-transform:scale(0); opacity:0;}
        50%{ -moz-transform:scale(1.3); opacity:0.4; }
        75%{ -moz-transform:scale(0.9); opacity:0.7;}
        100%{ -moz-transform:scale(1); opacity:1;}
}

@-webkit-keyframes bounce {
        0%{ -webkit-transform:scale(0); opacity:0;}
        50%{ -webkit-transform:scale(1.3); opacity:0.4;}
        75%{ -webkit-transform:scale(0.9); opacity:0.7;}
        100%{ -webkit-transform:scale(1); opacity:1;}
}



@keyframes drop {
  0% {
    transform: translateY(-40px) rotate(-45deg);
  }

  80% {
    transform: translateY(3px) rotate(-45deg);
  }

  100% {
    transform: translateY(0) rotate(-45deg);
  }
}

.drop {
  animation-name: drop;
  animation-fill-mode: both;
  animation-duration: 0.5s;
}
<div class='myBounceDiv'>
<div id="marker" class='pin bounce'></div>
<div class='pulse'></div>
</div>


先生 @Majid Hojati,如果我的答案解决了您的问题,请不要忘记接受它。提前致谢。 - Elvin Mammadov
非常感谢您的回答。实际上,我想让图钉从顶部掉落,并在单击时弹跳。这是否可能?在您的示例中,每次单击都会使图钉掉落,但我只想在单击时弹跳(稍微上下跳动)。 - Majid Hojati
哦,我明白了。当然可以。让我来。 - Elvin Mammadov
嗨,非常感谢。看起来Goldin的答案就是我所期望的。 - Majid Hojati

1

不要将CSS类更改为弹跳动画,然后再改回原始状态,而是可以在单击时添加(on click)并在1秒后删除(remove)pinmyBounceDiv中的类。需要注意的是,动画完成后还需要删除bounce类。

代码示例:

const pinEl = document.querySelector('.pin');

setTimeout(() => pinEl.classList.remove('bounce'), 1000);
function removeMiniBounce() {
    pinEl.classList.remove("miniBounce");
  }
pinEl.onclick = () => {
  pinEl.classList.add("miniBounce");
  setTimeout(removeMiniBounce, 1000);
}

"并且你的CSS将是:

"
@keyframes miniBounce {
    0%{ -webkit-transform:translateY(0px) rotate(-45deg);}
    30%{ -webkit-transform:translateY(-20px) rotate(-45deg);}
    60%{ -webkit-transform:translateY(0px) rotate(-45deg);}
    70%{ -webkit-transform:translateY(-5px) rotate(-45deg);}
    100%{ -webkit-transform:translateY(0) rotate(-45deg);}
}

.miniBounce {
  animation: miniBounce 0.4s ease-in-out; 
}

@golins 是的,谢谢,这正是我需要的。是否可能使用CSS实现像这个链接中的动画?http://dynamicsjs.com/examples/pin.html - Majid Hojati
你是指整个动画吗?完全可以实现,因为该动画是使用 matrix3d CSS 变换完成的(可能是由 dynamicsjs 生成)。您可以使用其他 transform 值(例如缩放、旋转和平移)来实现类似的动画效果。请查看您的示例中如何使用它们(例如 rotateZ: -45)。 - goldins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接