运行 css 动画来回点击
Run css animation back and forth on clicks
使用 css @keyframes
我试图在单击元素时将一些动画附加到该元素。
.animate {
animation-name: action;
animation-duration: 2s;
animation-timing-function: linear;
background-color: green;
}
@keyframes action {
0% {
background-color: gray;
}
50% {
background-color: red;
}
100% {
background-color: green;
}
}
单击时添加 .animate
class,框从灰色变为绿色。但是现在我想在再次单击它时将其动画回灰色(切换功能)。我尝试使用 animation-direction: reverse
使用相同的动画,但没有播放动画。动画最初不应该播放(我遇到过几次)。有什么建议我可以实现吗?
我会考虑使用 animation-play-state
属性 并且还会使用 infinite
和 alternate
。这个想法是 运行 动画并在它结束时停止它,然后再次 运行 等等:
const div = document.querySelector('.target')
div.addEventListener('click', (e) => {
div.classList.add('play');
setTimeout(function() {
div.classList.remove('play');
},2000)
})
.target {
width: 100px;
height: 100px;
background-color: gray;
cursor: pointer;
animation: action 2s linear alternate infinite;
animation-play-state:paused;
}
.play {
animation-play-state:running;
}
@keyframes action {
0% {
background-color: gray;
}
50% {
background-color: red;
}
100% {
background-color: green;
}
}
<div class="target">
</div>
用动画处理这种on/off变化总是很棘手,而且很难顺利无缝地处理重复的变化。
对于您的情况,我建议将其更改为单一过渡。在这种情况下,浏览器可以更好地处理 on/off 部分。要通过过渡实现背景颜色的双重变化,创建具有 3 种颜色的渐变,并更改渐变位置:
const div = document.querySelector('.test')
div.addEventListener('click', (e) => {
div.classList.toggle('play');
})
.test {
border: solid 1px black;
margin: 10px;
height: 100px;
width: 100px;
background-image: linear-gradient(gray 0%, gray 20%, blue 40%, blue 60%,
red 80%, red 100%);
background-size: 100% 9000%;
background-repeat: no-repeat;
background-position: center top;
transition: background-position .3s;
}
.play {
background-position: center bottom;
}
<div class="test">
</div>
好的,这是我的方法:
- 暂停动画,直到您添加
.enabled
(防止加载动画)
- 每次点击时切换
.active
class
- 重要:在
.active
中定义一个→不同的←动画,即使你前后晃动或摆动的动画是一样的,定义为一个副本。 (不然回来的路上会有没有的动画)
const div = document.querySelector('.target')
div.addEventListener('click', (e) => {
div.classList.add('active');
div.classList.toggle('play');
})
/* REF */
body, html { /* eye candy */
background: #444; display: flex; min-height: 100vh; align-items: center; justify-content: center;
}
div { /* eye candy */
width: 200px; height: 100px; border: 12px dashed #888; border-radius: 20px;
background: red;
}
/* prevents that there is an animation already on loading */
.active {
animation: trafficLight 2s linear;
}
.play {
border: 12px solid white; /* white border == play */
background: green;
/* yes, already setting for the way back!
fun fact: if you do not set a DIFFERENT animation, NO animation whatsoever will happen
(so also for simple bounce animations, where forth=back would be o.k.
you do need to clone it... varying time (1.001s) or direction is NOT enough.) */
animation: trafficLightBack 2s linear;
}
@keyframes trafficLight {
0% { background-color: green; }
50% { background-color: yellow; }
100% { background-color: red;}
}
@keyframes trafficLightBack {
0% { background-color: red; }
50% { background-color: yellow; }
100% { background-color: green;}
}
<div class="target"></div>
使用 css @keyframes
我试图在单击元素时将一些动画附加到该元素。
.animate {
animation-name: action;
animation-duration: 2s;
animation-timing-function: linear;
background-color: green;
}
@keyframes action {
0% {
background-color: gray;
}
50% {
background-color: red;
}
100% {
background-color: green;
}
}
单击时添加 .animate
class,框从灰色变为绿色。但是现在我想在再次单击它时将其动画回灰色(切换功能)。我尝试使用 animation-direction: reverse
使用相同的动画,但没有播放动画。动画最初不应该播放(我遇到过几次)。有什么建议我可以实现吗?
我会考虑使用 animation-play-state
属性 并且还会使用 infinite
和 alternate
。这个想法是 运行 动画并在它结束时停止它,然后再次 运行 等等:
const div = document.querySelector('.target')
div.addEventListener('click', (e) => {
div.classList.add('play');
setTimeout(function() {
div.classList.remove('play');
},2000)
})
.target {
width: 100px;
height: 100px;
background-color: gray;
cursor: pointer;
animation: action 2s linear alternate infinite;
animation-play-state:paused;
}
.play {
animation-play-state:running;
}
@keyframes action {
0% {
background-color: gray;
}
50% {
background-color: red;
}
100% {
background-color: green;
}
}
<div class="target">
</div>
用动画处理这种on/off变化总是很棘手,而且很难顺利无缝地处理重复的变化。
对于您的情况,我建议将其更改为单一过渡。在这种情况下,浏览器可以更好地处理 on/off 部分。要通过过渡实现背景颜色的双重变化,创建具有 3 种颜色的渐变,并更改渐变位置:
const div = document.querySelector('.test')
div.addEventListener('click', (e) => {
div.classList.toggle('play');
})
.test {
border: solid 1px black;
margin: 10px;
height: 100px;
width: 100px;
background-image: linear-gradient(gray 0%, gray 20%, blue 40%, blue 60%,
red 80%, red 100%);
background-size: 100% 9000%;
background-repeat: no-repeat;
background-position: center top;
transition: background-position .3s;
}
.play {
background-position: center bottom;
}
<div class="test">
</div>
好的,这是我的方法:
- 暂停动画,直到您添加
.enabled
(防止加载动画) - 每次点击时切换
.active
class - 重要:在
.active
中定义一个→不同的←动画,即使你前后晃动或摆动的动画是一样的,定义为一个副本。 (不然回来的路上会有没有的动画)
const div = document.querySelector('.target')
div.addEventListener('click', (e) => {
div.classList.add('active');
div.classList.toggle('play');
})
/* REF */
body, html { /* eye candy */
background: #444; display: flex; min-height: 100vh; align-items: center; justify-content: center;
}
div { /* eye candy */
width: 200px; height: 100px; border: 12px dashed #888; border-radius: 20px;
background: red;
}
/* prevents that there is an animation already on loading */
.active {
animation: trafficLight 2s linear;
}
.play {
border: 12px solid white; /* white border == play */
background: green;
/* yes, already setting for the way back!
fun fact: if you do not set a DIFFERENT animation, NO animation whatsoever will happen
(so also for simple bounce animations, where forth=back would be o.k.
you do need to clone it... varying time (1.001s) or direction is NOT enough.) */
animation: trafficLightBack 2s linear;
}
@keyframes trafficLight {
0% { background-color: green; }
50% { background-color: yellow; }
100% { background-color: red;}
}
@keyframes trafficLightBack {
0% { background-color: red; }
50% { background-color: yellow; }
100% { background-color: green;}
}
<div class="target"></div>