在一些界面中,我想做动画。因为transform属性比其他CSS属性优化得多,所以我将使用它。
With transform:scale():当元素纵横比不变时,没有问题。当比率应该改变时,我找到的解决办法是放一个容器,在这个容器里放一个内容器。然后将反向变换应用到内部块,以便在动画期间和动画之后保持比率。
我做了一支笔来测试这个想法,它确实有效,但是在动画中有一个问题:内部块在动画中看起来被拉伸了。我不明白为什么动画时间是一样的,放松是线性的。
https://codepen.io/AdamElio/pen/PabejP
(单击菜单切换动画)

document.querySelector('#menu').addEventListener('click', function() {
    this.classList.toggle('collapsedd')
});

#menu {
  margin: 30px;
  padding: 15px;
  background: white;
  width: 150px;
  overflow: hidden;
  transform-origin: top center;
  transition: transform .5s linear;
}

#menu.collapsedd {
  transform: scaleY(.2);
}

#menu .inner {
  transition: transform .5s linear;
  transform-origin: top center;
}

#menu.collapsedd .inner {
  transform: scaleY(5);
}

#menu .inner ul {
  padding: 0;
  margin: 0;
  list-style: none;
}

<nav id="menu">
  <div class="inner">
    <h5>Menu</h5>
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
      <li>Link 4</li>
    </ul>
  </div>
</nav>

<div id="transform"></div>

最佳答案

发生这种情况是因为发生转换时计数器转换不相同。考虑到您的示例,容器将从scaleY(0.2)转到scaleY(1),而子容器将从scaleY(5)转到scaleY(1)
在转换的末尾和开头,这将起作用,因为容器和子转换将“取消”:
起点:0.2*5=1
结束:1*1=1
但过渡的中间步骤并非如此。例如,当转换完成50%时:
容器刻度:0.2+(1-0.2)*0.5=0.6
子scaleY:5+(1-5)*0.5=3
容器scaleY*子scaleY:0.6*3=1.8
请查看下面的图表,了解此比例的变化情况:
html - CSS动画中的逆变换-LMLPHP
紫色的线在转换期间显示子scaleY,蓝色的线显示容器scaleY,深黄色的线显示容器scaleY*child scaleY
因此,为了在转换过程中真正取消容器转换,您需要使用一个easing函数来保存整个转换的表达式container scale * child scale = 1。这可不是件容易的事。

10-07 20:43