在类之间切换会使动画无法进行,只是跳到最后



我正试图通过将底部和顶部的线平移到中间,然后旋转到X来制作汉堡菜单的动画,并希望在单击X时反转动画。使用jquery,我可以打开类菜单和关闭菜单。当我删除菜单关闭动画的CSS时,它会很好地启动,但当我将CSS添加回动画时,动画会跳到最后一帧。它形成了我想要的,但就是拒绝完全使用动画。

CSS

.navbar .mobile-menu.menu-open .line::before {
animation: menu-open-top 250ms linear forwards;
}
.navbar .mobile-menu.menu-open .line {
animation: menu-middle 250ms linear forwards;
}
.navbar .mobile-menu.menu-open .line::after {
animation: menu-open-bottom 250ms linear forwards;
}
.navbar .mobile-menu.menu-closed .line::before {
animation: menu-open-top 250ms linear reverse;
}
.navbar .mobile-menu.menu-closed .line {
animation: menu-middle 250ms linear reverse;
}
.navbar .mobile-menu.menu-closed .line::after {
animation: menu-open-bottom 250ms linear reverse;
}

动画

@keyframes menu-open-top {
30% {
bottom: 0;
}
60% {
bottom: 0;
transform: rotate(0) translate(0);
}
100% {
transform: rotate(45deg) translate(5px, 5px);
visibility: visible;
}
}
@keyframes menu-middle {
40% {
visibility: hidden;
}
to {
visibility: hidden;
}
}
@keyframes menu-open-bottom {
30% {
top: 0;
}
60% {
top: 0;
transform: rotate(0) translate(0);
}
100% {
transform: rotate(-45deg) translate(6px, -6px);
visibility: visible;
}
}

JS-

$(".mobile-menu").click(expandMenu);
function expandMenu() {
$(".primary-nav").toggleClass("menu-expand");
$(this).toggleClass("menu-open menu-closed");
}

我一定错过了什么,或者我可能需要为反向动画添加新的关键帧,但这感觉没有必要。

编辑:这是html以及

HTML

<div class="mobile-menu menu-closed">
<div class="line"></div>
</div>

以下是如何使用简单的道具值更改和谨慎的计时来实现这一点。我想也可以使用@keyframe动画来完成,但我发现它们更难跟踪/控制/同步,至少在这种情况下,考虑到它(基本上(是一个两步动画。

document.querySelector('.mobile-menu').addEventListener('click', ({
target
}) => {
target.closest('.mobile-menu').classList.toggle('menu-open');
})
.mobile-menu {
--duration: 0.42s;
--size: 3rem;
--padding: 0.5rem;
--color: red;
--distance-timing: cubic-bezier(0.5, 0, 0.3, 1);
--rotation-timing: cubic-bezier(0.4, 0, 0.2, 1);
width: var(--size);
height: var(--size);
padding: var(--padding);
display: flex;
flex-direction: column;
justify-content: space-between;
cursor: pointer;
}
.mobile-menu * {
box-sizing: border-box;
}
.mobile-menu>div {
border: 1px solid var(--color);
height: 0;
width: 100%;
position: relative;
transform-origin: 50% 50%;
transition:
top calc(0.6 * var(--duration)) var(--distance-timing) calc(0.4 * var(--duration)),
bottom calc(0.6 * var(--duration)) var(--distance-timing) calc(0.4 * var(--duration)), 
transform calc(0.8 * var(--duration)) var(--rotation-timing) 0s;
}
.mobile-menu> :nth-child(1) {
top: calc(var(--padding)/2);
}
.mobile-menu> :nth-child(3) {
bottom: calc(var(--padding)/2);
}
.mobile-menu.menu-open>div {
transition:
top calc(0.4 * var(--duration)) var(--distance-timing) 0s,
bottom calc(0.4 * var(--duration)) var(--distance-timing) 0s,
transform calc(0.8 * var(--duration)) var(--rotation-timing) calc(0.2 * var(--duration));
}
.mobile-menu.menu-open> :nth-child(1) {
top: calc(50% - 1px);
transform: rotate(0.125turn);
}
.mobile-menu.menu-open> :nth-child(2) {
transform: rotate(0.125turn);
}
.mobile-menu.menu-open> :nth-child(3) {
bottom: calc(50% - 1px);
transform: rotate(-0.125turn);
}
<div class="mobile-menu">
<div></div>
<div></div>
<div></div>
</div>

同样的事情,在SCSS中:https://jsfiddle.net/websiter/dybre2f9/
我已经将这些值提取到CSS变量中,因此可以轻松地重用和修改。请随意调整以满足您的喜好。

注意:我之所以使用bottomtop来制作动作动画(而不是translateY,后者的性能略高(,是因为我希望这两个动画完全独立,以便我能够使用各种重叠的值和计时功能。我所提出的并没有100%遵守这一要求(比如,它与旋转和运动稍微重叠——但我是故意这样做的,因为不重叠看起来太机械了(。重叠时,整个动画看起来更加有机。这就像按钮是活的,很高兴被要求做动画。或者我只是有点疯了,我不知道。。。

相关内容

最新更新