react-transition-group 动画的布局中断
Posted
技术标签:
【中文标题】react-transition-group 动画的布局中断【英文标题】:Layout breaks on react-transition-group animation 【发布时间】:2019-03-20 09:03:52 【问题描述】:我正在尝试熟悉react-transition-group
,但遇到了一些问题。在一个简单的组件中,它显示当前计数器并在increment
或decrement
上为显示的值设置动画,当输入新值时,它会移动前一个值,从而产生突然的效果。这可能是因为具有不透明度0
的新元素进入圆顶并且两个值同时显示。
整个组件如下所示:
import React, Component from "react";
import TransitionGroup, CSSTransition from "react-transition-group";
import "./App.css";
class App extends Component
state =
progress: 0
;
incr = () =>
this.setState(
progress: this.state.progress + 1
);
;
decr = () =>
this.setState(
progress: this.state.progress - 1
);
;
render()
return (
<div className="App">
<TransitionGroup>
<CSSTransition
in=true
appear=true
key=this.state.progress
timeout=2000
classNames="slide"
>
<div key=this.state.progress>this.state.progress</div>
</CSSTransition>
</TransitionGroup>
<button onClick=this.decr>decr</button>
<button onClick=this.incr>incr</button>
</div>
);
export default App;
过渡类如下所示:
/* slide enter */
.slide-enter
opacity: 0;
transform: scale(0.97) translateX(5px);
z-index: 1;
.slide-enter.slide-enter-active
opacity: 1;
transform: scale(1) translateX(0);
transition: opacity 3000ms linear 1000ms, transform 3000ms ease-in-out 1000ms;
/* slide exit */
.slide-exit
opacity: 1;
transform: scale(1) translateX(0);
.slide-exit.slide-exit-active
opacity: 0;
transform: scale(0.97) translateX(5px);
transition: opacity 1500ms linear, transform 1500ms ease-out;
.slide-exit-done
opacity: 0;
我想实现以下行为:在递增/递减时,当前显示的计数器逐渐消失,而新的计数器在当前计数器不存在后淡入。
【问题讨论】:
【参考方案1】:这可能是因为不透明度为 0 的新元素进入圆顶,并且两个值同时显示。
是的,就是这样。您可以使用 position: absolute
从文档流中删除元素,并且您可能还需要以某种方式补偿从文档流中删除这些元素的事实。
<TransitionGroup>
<CSSTransition
in=true
appear=true
key=this.state.progress
timeout=2000
classNames="slide"
>
<div className="animating" key=this.state.progress>
this.state.progress
</div>
</CSSTransition>
</TransitionGroup>
CSS
.animating
position: absolute;
button:first-of-type
margin-top: 50px;
没有 React 过渡组
JS
import React, Component from "react";
import "./App.css";
class App extends Component
state =
progress: 0,
transition: "entering" /* entering | exiting */
;
instanceVariables =
temporaryProgress: 0,
timeoutId: null
;
animate = () =>
clearTimeout(this.instanceVariables.timeoutId);
this.instanceVariables.timeoutId = setTimeout(() =>
this.setState(
progress: this.instanceVariables.temporaryProgress,
transition: "entering"
);
, 1000);
this.setState(
transition: "exiting"
);
;
incr = () =>
this.instanceVariables.temporaryProgress += 1;
this.animate();
;
decr = () =>
this.instanceVariables.temporaryProgress -= 1;
this.animate();
;
render()
return (
<div className="App">
<div className=`animate $this.state.transition`>
this.state.progress
</div>
<button onClick=this.decr>decr</button>
<button onClick=this.incr>incr</button>
</div>
);
export default App;
CSS
.animate
transition: opacity 1s linear, transform 1s ease-in-out;
.animate.exiting
transform: translateX(20px);
opacity: 0;
.animate.entering
transform: translateX(0);
opacity: 1;
【讨论】:
感谢您的回答!但是有没有办法延迟退出动画,所以它会在新动画进入之前退出?在更复杂的布局中,我认为将absolute
赋予元素会破坏很多东西。谢谢!
position: absolute
正是我为 my app shell layout 所做的(它使用 React Transition Group 进行路由转换)。如果你只希望一次出现一个元素,那么最好不要使用 React Transition Group,因为你真的不需要它。你可以使用普通的 React。
如果我只想将退出元素的不透明度从 1 设置为 0,反之亦然以进入元素,我将如何实现这一点?我现在正在与布局作斗争,以使我想要过渡的元素成为绝对的,但到目前为止它还不起作用,所以任何关于我如何在没有过渡组的情况下做到这一点的建议都非常受欢迎!再次感谢,这意味着很多
@DimitryIvashchuk 当然,我已经更新了我的答案以包含一个示例。
感谢您的帮助和建议,我会根据他们的努力使其工作!以上是关于react-transition-group 动画的布局中断的主要内容,如果未能解决你的问题,请参考以下文章
react-transition-group动画以及数字滚动效果实现
使用 ReactDOM createPortal 为 react-transition-group 设置动画
如何使用 React-Transition-Group 显示和隐藏带有动画的模态/对话框?