反转css关键帧动画
Reverse css keyframe animation
我已经为 svg 路径使用关键帧编写了一个 css 动画
path {
animation: anim 1s linear;
animation-fill-mode: forwards;
}
@keyframes anim {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 10 L 30 30');
}
}
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent" />
如果您单击 svg,您可以看到正在运行的动画。现在,如果您再次单击,我希望它以动画形式恢复到其原始状态。我试过添加
transition: all 1s ease-out;
和
animation-direction: alternate;
但是还是没有动画回到初始状态。
所以问题是,我怎样才能动画回来?
使用过渡你可以很容易地做到这一点,但动画会略有不同:
const svg = document.querySelector('svg');
svg.addEventListener('click', () => {
svg.classList.toggle('close');
});
svg {
border: 1px solid blue;
}
svg path {
transition: 0.2s all linear;
}
svg.close path.top {
d: path('M10 10 L 30 30');
}
svg.close path.middle {
d: path('M20 20 L 20 20');
}
svg.close path.bottom {
d: path('M10 30 L 30 10');
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
<path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
<path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>
另一个想法是依赖 animationiteration
,技巧是 运行 一个 infinite
动画,然后在每次迭代时停止它。
const svg = document.querySelector('svg');
const path = document.querySelector('svg path');
svg.addEventListener('click', () => {
svg.classList.toggle('close');
});
path.addEventListener('animationiteration', () =>{
svg.classList.toggle('close');
});
svg {
border: 1px solid blue;
}
path.top {
animation: close-top 0.2s linear infinite alternate;
}
path.middle {
animation: close-middle 0.2s linear infinite alternate;
}
path.bottom {
animation: close-bottom 0.2s linear infinite alternate;
}
svg:not(.close) path {
animation-play-state: paused;
}
svg.close path {
animation-play-state: running;
}
@keyframes close-top {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 10 L 30 30');
}
}
@keyframes close-middle {
to {
d: path('M20 20 L 20 20');
}
}
@keyframes close-bottom {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 30 L 30 10');
}
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
<path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
<path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>
我已经为 svg 路径使用关键帧编写了一个 css 动画
path {
animation: anim 1s linear;
animation-fill-mode: forwards;
}
@keyframes anim {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 10 L 30 30');
}
}
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent" />
如果您单击 svg,您可以看到正在运行的动画。现在,如果您再次单击,我希望它以动画形式恢复到其原始状态。我试过添加
transition: all 1s ease-out;
和
animation-direction: alternate;
但是还是没有动画回到初始状态。
所以问题是,我怎样才能动画回来?
使用过渡你可以很容易地做到这一点,但动画会略有不同:
const svg = document.querySelector('svg');
svg.addEventListener('click', () => {
svg.classList.toggle('close');
});
svg {
border: 1px solid blue;
}
svg path {
transition: 0.2s all linear;
}
svg.close path.top {
d: path('M10 10 L 30 30');
}
svg.close path.middle {
d: path('M20 20 L 20 20');
}
svg.close path.bottom {
d: path('M10 30 L 30 10');
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
<path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
<path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>
另一个想法是依赖 animationiteration
,技巧是 运行 一个 infinite
动画,然后在每次迭代时停止它。
const svg = document.querySelector('svg');
const path = document.querySelector('svg path');
svg.addEventListener('click', () => {
svg.classList.toggle('close');
});
path.addEventListener('animationiteration', () =>{
svg.classList.toggle('close');
});
svg {
border: 1px solid blue;
}
path.top {
animation: close-top 0.2s linear infinite alternate;
}
path.middle {
animation: close-middle 0.2s linear infinite alternate;
}
path.bottom {
animation: close-bottom 0.2s linear infinite alternate;
}
svg:not(.close) path {
animation-play-state: paused;
}
svg.close path {
animation-play-state: running;
}
@keyframes close-top {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 10 L 30 30');
}
}
@keyframes close-middle {
to {
d: path('M20 20 L 20 20');
}
}
@keyframes close-bottom {
50% {
d: path('M20 20 L 20 20');
}
100% {
d: path('M10 30 L 30 10');
}
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
<path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
<path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>