进入DOM的元素是否有流畅的CSS高度属性? Jank在使用Semantic-UI-React Transitions时发生

问题描述 投票:0回答:1

我不确定这是否是提出这个问题的适当场所;我考虑过软件推荐,但我想我先在这里试一试。

我正在创建一个PWA,并且每次迭代我都非常希望专注于使它看起来/感觉不那么笨拙和尽可能平滑。好吧,就像一个原生应用程序。

所以这就是问题 - 我正在使用Semantic-UI-React提供的转换(动画),虽然它在占据空间的元素时工作得很漂亮,但我想知道是否存在处理行为的实践或模式相邻的DOM元素到一个动画的元素?

我在下面提供了一个GIF来说明我的意思。我想我可以将动画元素从表单的容器中移出来防止jank,但我想知道是否有更优雅的模式或方法...

谢谢!

enter image description here

javascript css-transitions semantic-ui-react react-animations jank
1个回答
1
投票

不幸的是,没有特别优雅的方法。

关于帖子标题中的问题,一种常见的方法是为新元素的height制作动画。如果你不知道元素的高度,不幸的是从0pxauto does not yet work的动画,但你可以通过从max-height动画0px到一个稍微大于你期望元素的最大大小的值来捏造它。

但是不要这样做。

它将导致浏览器在每个动画帧上布局页面,并且几乎肯定会在低端设备上进行布局。

相反,你最好动画transform

最常见的方法是:

  1. 在将新元素添加到DOM之前抓取元素的原始位置(使用getBoundingClientRect()等)(可能使用getSnapshotBeforeUpdate,除非你使用钩子,在这种情况下你可以使用useRef来达到类似的效果) )。
  2. 在添加新元素(您可能通过使用具有合适的transform函数的scale()进行动画处理)之后,计算偏移元素现在的增量,与之相比。
  3. 将delta的负值设置为transform动画为零(即FLIP方法)。例如。如果元素已经向下移动300px,则将transformtranslateY(-300px)动画到none

当然,您需要为受影响的流中的所有元素执行此操作,因此最简单的方法是将它们全部放在一个容器中,然后对其进行动画处理。

关于第三点,你有一些技术选择,但没有一个是伟大的:

  • CSS转换。这些是最简单的,但您必须触发样式刷新才能获得负增量起点。例如 elem.style.transform = `translateY(-${offset}px)`; elem.style.transition = `transform .3s`; getComputedStyle(elem).transform; // Flush style elem.style.transform = `none`;
  • CSS动画。使用CSSOM动态生成@keyframes规则很痛苦,但至少你不需要触发样式刷新(为方便起见,你可以设置一个带有隐式to-keyframe的动画)。 @keyframes random-id { from: { translateY(-300px); } }
  • 网络动画。这可能是最合适的。 elem.animate({ transform: [ `translateY(-${offset}px)`, 'none' ] }, 300); // In future when browsers ship support for implicit to/from keyframes: elem.animate({ transform: `translateY(-${offset}px)`, offset: 0 }, 300); 不幸的是,Safari仅在Tech Preview中支持Web Animations,因此Safari用户将获得未动画版本,直到下一个Safari版本发布。边缘用户也将获得未动画版本,直到基于Chromium的Edge发布。还有一个polyfill,但目前还没有积极维护。

如果你正在使用React,Animating the Unanimatable是一篇有用的文章。

另一个棘手的部分是确保滚动不会跳转,您可能需要查看滚动锚定。

© www.soinside.com 2019 - 2024. All rights reserved.