我希望在单击按钮时将div设置为右边的动画,然后在单击相同的按钮时再次向左设置动画。我想只使用一个关键帧声明。这可以通过交换类来实现吗?
我已经在CodePen中尝试了这个,但不幸的是,div在第一个动画后重新拍摄,然后拒绝第二次动画。
我没有使用css过渡,因为我希望能够使用css动画的功能,如弹跳效果。
Codepen:http://codepen.io/anon/pen/Vaadao
HTML:
<div class="container">
<div class="one">One</div>
<div>
<button>Clicky</button>
SCSS:
.container {
position: absolute;
perspective: 800px;
> div {
position: absolute;
padding: 20px;
text-align: center;
width: 100px;
}
> div.do-the-slide {
animation: moveOver 1s ease-out;
}
> div.do-the-slide-back {
animation: moveOver 1s reverse ease-out;
}
> .one {
background: red;
}
}
button {
margin-top: 100px;
}
@keyframes moveOver {
from {
transform: translateX(0px);
}
to {
transform: translateX(100px);
}
}
JS:
window.addEventListener("load", function() {
var movedOver = false;
document.querySelector("button").addEventListener("click", function() {
var buttonEl = document.querySelector(".one");
if(movedOver) {
buttonEl.classList.remove("do-the-slide");
buttonEl.classList.add("do-the-slide-back");
} else {
buttonEl.classList.remove("do-the-slide-back");
buttonEl.classList.add("do-the-slide");
}
});
});
答案 0 :(得分:1)
也许您正在寻找forwards
,但即使这样,也需要进行转换才能简化。
p span {
display: inline-block;
transition: 1s;
}
p:hover span {
animation: 1s moveOver forwards;
}
@keyframes moveOver {
to {
transform: translateX(100px);
}
&#13;
<p><span>span</span>
</p>
&#13;
如果你想使用单个动画,你最终将不得不处理暂停和步骤,我甚至不确定它是否易于处理或可能。我觉得这里没什么好玩的。)
对于反弹效果,50%的最终值应该足够好:
p span {
display: inline-block;
transition: 1s;
}
p:hover span {
animation: 2s moveOver infinite;
}
@keyframes moveOver {
50% {
transform: translateX(100px);
}
&#13;
<p><span>span</span>
</p>
&#13;
答案 1 :(得分:1)
好吧,所以在摆弄了一段时间之后,我想出了一个我认为可以接受的解决方案,使用一个关键帧声明来驱动两个动画方向。关键是迫使浏览器基本上通过重绘重置,如下所述:https://css-tricks.com/restart-css-animation/(感谢Jacob Gray发布该引用)。
一旦我使用了重置,我使用javascript(是的,这需要javascript)在动画回来时添加反向(这可能是在一个单独的类中,只是添加该className)。
而且,它有效。我现在可以使用一个关键帧声明在两个方向上制作动画。非常时髦,并大大减少了CSS代码。
CodePen:http://codepen.io/risingtiger/pen/zqqMpv
HTML:
<div class="container">
<div class="one">One</div>
</div>
<button>Clicky</button>
CSS:
.container {
position: absolute;
perspective: 800px;
> div {
position: absolute;
padding: 20px;
text-align: center;
width: 100px;
}
> div.do-the-slide {
animation: moveOver 1s ease-in-out;
animation-fill-mode: forwards;
}
> .one {
background: red;
}
}
button {
margin-top: 100px;
}
@keyframes moveOver {
from {
transform: translate3d(0px, 0, 0);
}
20% {
transform: translate3d(-20px, 0, 0);
}
80% {
transform: translate3d(120px, 0, 0);
}
to {
transform: translate3d(100px, 0, 0);
}
}
JS:
window.addEventListener("load", function() {
var movedOver = false;
var direction = "";
document.querySelector("button").addEventListener("click", function() {
var el = document.querySelector(".one");
el.classList.remove("do-the-slide");
el.offsetWidth = el.offsetWidth;
if(direction === "toRight") {
direction = "toLeft";
el.style.animationDirection = "reverse";
} else {
direction = "toRight";
el.style.animationDirection = "";
}
el.classList.add("do-the-slide");
});
});
答案 2 :(得分:-2)
我根据这篇文章和此处的css-tricks文章codepen
HTML
<h2>Single keyframe-track burger collection</h2>
<p>(each span uses only one track to play for- and backwards)</p>
<div class="wrapper">
<div class="cell">
<h3>Default</h3>
<div>
<button class="burger">
<span class="burger__bar"></span>
<span class="burger__bar"></span>
<span class="burger__bar"></span>
</button>
</div>
</div>
<div class="cell">
<h3>Merge</h3>
<div>
<button class="burger burger--merge">
<span class="burger__bar"></span>
<span class="burger__bar"></span>
<span class="burger__bar"></span>
</button>
</div>
</div>
<div class="cell">
<h3>Rotate</h3>
<div>
<button class="burger burger--rotate">
<span class="burger__bar"></span>
<span class="burger__bar"></span>
<span class="burger__bar"></span>
</button>
</div>
</div>
<div class="cell">
<h3>Spin</h3>
<div>
<button class="burger burger--spin">
<span class="burger__bar"></span>
<span class="burger__bar"></span>
<span class="burger__bar"></span>
</button>
</div>
</div>
</div>
CSS
body {
position: relative;
padding: 0;
margin: 0;
width: 100%;
height: 100vh;
background: radial-gradient(#5E802B, #2F4016);
font-family: sans-serif;
text-align: center;
h2,
h3,
p {
color: rgb(255, 255, 255);
}
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
}
.cell {
flex-grow: 1;
flex-basis: 50%;
margin: 0 20px;
display: flex;
flex-direction: column;
div {
margin-top: auto;
}
}
/****************
* Burger Styles *
*****************/
.burger {
position: relative;
width: 60px;
height: 60px;
padding: 0;
border: none;
background-color: transparent;
&__bar {
height: 10%;
border-radius: 2px;
width: 80%;
background-color: white;
display: block;
position: absolute;
left: 50%;
animation-timing-function: ease-in-out;
animation-play-state: paused;
animation-duration: .4s;
animation-fill-mode: both;
&:nth-child(1) {
top: 25%;
transform: translate(-50%, 0%);
}
&:nth-child(2) {
top: 50%;
transform: translate(-50%, -50%);
}
&:nth-child(3) {
bottom: 25%;
transform: translate(-50%, 0%);
}
}
&.close .burger__bar {
animation-direction: reverse;
}
&.open .burger__bar {
animation-direction: normal;
}
// default
&.animate .burger__bar {
animation-play-state: running;
&:nth-child(1) {
animation-name: default-top;
}
&:nth-child(2) {
animation-name: default-middle;
}
&:nth-child(3) {
animation-name: default-bottom;
}
}
&--merge.animate .burger__bar {
animation-duration: .6s;
animation-timing-function: ease;
&:nth-child(1) {
animation-name: merge-top;
}
&:nth-child(2) {
animation-name: merge-middle;
}
&:nth-child(3) {
animation-name: merge-bottom;
}
}
&--rotate.animate .burger__bar {
&:nth-child(1) {
animation-name: rotate-top;
}
&:nth-child(2) {
animation-name: rotate-middle;
}
&:nth-child(3) {
animation-name: rotate-bottom;
}
}
&--spin.animate .burger__bar {
animation-duration: 1s;
animation-timing-function: ease;
&:nth-child(1) {
animation-name: spin-top;
}
&:nth-child(2) {
animation-name: spin-middle;
}
&:nth-child(3) {
animation-name: spin-bottom;
}
}
}
/*__________________
DEFAULT
____________________*/
@keyframes default-top {
50% {
top:50%;
transform: translate(-50%, -50%) rotate(0);
}
100% {
top:50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
}
@keyframes default-middle {
50%, 100% {visibility:hidden;}
}
@keyframes default-bottom {
0% {}
25% {}
50% {
bottom:50%;
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
bottom:50%;
transform: translate(-50%, 50%) rotate(45deg);
}
}
/*__________________
MERGE
____________________*/
@keyframes merge-top {
20% {
top:50%;
transform: translate(-50%, -50%) rotate(0) scale(1, 1);
//width: 100%;
}
50% {
transform: translate(-50%, -50%) rotate(0) scale(0.2, 1);
//width: 20%;
}
60% {
transform: translate(-50%, -50%) rotate(-45deg) scale(0.2, 1);
//width: 20%;
}
100% {
top:50%;
transform: translate(-50%, -50%) rotate(-45deg) scale(1, 1);
//width: 100%;
}
}
@keyframes merge-middle {
50% {
transform: translate(-50%, -50%) scale(0, 1);
}
51%{visibility:hidden;}
99% {
transform: translate(-50%, -50%) scale(0, 1);
}
100% {visibility:hidden;}
}
@keyframes merge-bottom {
20% {
bottom:40%;
transform: translate(-50%, -50%) rotate(0deg) scale(1, 1);
}
50% {
transform: translate(-50%, -50%) rotate(0deg) scale(0.2, 1);
}
60% {
transform: translate(-50%, -50%) rotate(45deg) scale(0.2, 1);
}
100% {
bottom:40%;
transform: translate(-50%, -50%) rotate(45deg) scale(1, 1);
}
}
/*__________________
ROTATE
____________________*/
@keyframes rotate-top {
50% {
top:50%;
transform: translate(-50%, -50%) rotate(0deg);
}
100% {
top:50%;
transform: translate(-50%, -50%) rotate(45deg);
}
}
@keyframes rotate-middle {
50% {transform: translate(-50%, -50%) rotate(0deg);}
100% {transform: translate(-50%, -50%) rotate(135deg);}
}
@keyframes rotate-bottom {
50% {
bottom:50%;
transform: translate(-50%, 50%) rotate(0deg);
}
100% {
bottom:50%;
transform: translate(-50%, 50%) rotate(45deg);
}
}
/*__________________
SPIN
____________________*/
@keyframes spin-top {
50% {
top:50%;
transform: translate(-50%, -50%) rotate(0deg);
}
75% {
transform: translate(-50%, -50%) rotate(360deg);
}
100% {
top:50%;
transform: translate(-50%, -50%) rotate(315deg);
}
}
@keyframes spin-middle {
50% {visibility:hidden;}
100% {visibility:hidden;}
}
@keyframes spin-bottom {
50% {
bottom:50%;
transform: translate(-50%, 50%) rotate(0deg);
}
75% {
transform: translate(-50%, 50%) rotate(450deg);
}
100% {
bottom:50%;
transform: translate(-50%, 50%) rotate(405deg);
}
}
JavaScript
burgers = document.querySelectorAll('.burger');
for (let i = 0; i < burgers.length; i++) {
burgers[i].addEventListener("click", function(){
this.classList.remove("animate");
var bars = this.querySelectorAll('.burger__bar');
for (let i = 0; i < bars.length; i++) {
// Reset span animations - https://css-tricks.com/restart-css-animation/
void bars[i].offsetWidth;
}
if (this.classList.contains("open")){
this.classList.remove("open");
this.classList.add("close");
} else {
this.classList.remove("close");
this.classList.add("open");
}
this.classList.add("animate");
});
};