我的 UI 动画使用 javascript 添加和删除动画 类 很草率——有更好的方法吗?

My UI animation is sloppy using javascript to add and remove animation classes—is there a better way?

我正在尝试为博客制作这个新闻项目组件界面。每个项目显示一个故事图像和文章的一些文本。滚动新闻项目应该“揉搓”图像并显示文章的更多文本。我不明白为什么当你翻转项目时我的动画没有保持,然后它在执行“unscrunching”之前完全重置。

有附加和分离项目的关键帧动画:

@keyframes scrunch {
  from {
    height: 50%;
  }

  to {
    height: 10%;
  }
}

@keyframes unscrunch {
  from {
    height: 10%;
  }

  to {
    height: 50%;
  }
}

.scrunch {
  animation: scrunch 1s;
}

.unscrunch {
  animation: unscrunch 1s;
}

然后我只是在新闻项目 class 列表中添加和删除那些 classes:

const scrunchyBox = document.getElementById('scrunchyBox1');
const children = scrunchyBox.childNodes;
console.dir(children);
const scrunchyBoxHead = children[1];

scrunchyBox.addEventListener('pointerover', (event) => {
  scrunchyBoxHead.classList.remove('unscrunch');
  scrunchyBoxHead.classList.add('scrunch');
});

scrunchyBox.addEventListener('pointerout', (event) => {
  scrunchyBoxHead.classList.remove('scrunch'); 
  scrunchyBoxHead.classList.add('unscrunch');
});

看起来很简单,但无论我做什么看起来都很恶心。我所做的一切都在 my Codepen.

结束了
  1. 您可以使用 animation-fill-mode: forwards; 将动画保留在其最终状态,如回答此问题时所述:Maintaining the final state at end of a CSS3 animation

  2. 如果您在动画中途从框中移除指针,它仍然会看起来很糟糕。我不确定您为什么不想简单地使用 CSS :hover 进行过渡。

您可以将 transition 属性 与 :hover 伪 class 一起使用。这与您尝试使用 javascript.

所做的相同

为此,只需在 css 文件中添加几行即可。

/* new block */
.scrunchyBox:hover .sectionHead {
  height: 10%;
}
/* new block */
.scrunchyBox:hover .datedot {
  transform: scale(0.45) translate(60px, -72px);
}

.scrunchyBox > .sectionHead {
  transition: all 0.5s ease-in-out; /* new line */
}
.datedot {
  transition: all 0.5s ease-in-out; /* new line */
}

body {
  background-color: #ccc;
  font-size: 18px;
}

.scrunchyBox {
  color: #333;
  position: relative;
  background-color: #fff;
  width: 400px;
  height: 400px;
  margin: 0 auto;
  padding: 20px;
  overflow: hidden;
  filter: drop-shadow(4px 4px 4px #333);
}

/* new block */
.scrunchyBox:hover .sectionHead {
  height: 10%;
}
/* new block */
.scrunchyBox:hover .datedot {
  transform: scale(0.45) translate(60px, -72px);
}

.scrunchyBox > .sectionHead {
  width: 400px;
  height: 250px;
  background-color: #3ab7f4;
  padding: 0;
  margin: 0 auto;
  transition: all 0.5s ease-in-out; /* new line */
}

.datedot {
  position: absolute;
  top: 30px;
  right: 30px;
  background-color: rgba(0, 0, 0, 0.3);
  padding: 12px;
  border-radius: 60px;
  width: 60px;
  height: 60px;
  transition: all 0.5s ease-in-out; /* new line */
}

.datedot > span {
  font-family: 'Trebuchet MS', sans-serif;
  color: rgba(255, 255, 255, 1);
  text-align: center;
  display: block;
  margin: 0;
}

.datedot > span.day {
  font-size: 2.2em;
  font-weight: bold;
  line-height: 0.8em;
  padding: 0;
}

.datedot > span.month {
  font-size: 1.3em;
  font-weight: normal;
  text-transform: uppercase;
  padding: 0;
}

.scrunchyBox > h2 {
  font-family: 'Trebuchet MS', sans-serif;
  font-size: 1.2em;
  line-height: 1em;
  padding: 0;
}

.scrunchyBox > p {
  font-family: 'Georgia', serif;
  font-size: 1.4em;
}
<div id="scrunchyBox1" class="scrunchyBox">
  <div class="sectionHead">
    <div class="datedot">
      <span class="day">30</span>
      <span class="month">Oct</span>
    </div>
  </div>
  <h2>A Headline for the Scrunchy Box</h2>
  <p>
    This is some text that would normally be some text that the reader would want to see more of. It gets cut off here by other elements, but then other elements "scrunch" in order to reveal more of the text for a preview.
  </p>
</div>