反应过渡组动画布局中断
Layout breaks on react-transition-group animation
我正在尝试熟悉 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;
}
我想实现以下行为:在 increment/decrement 当前显示的计数器逐渐消失,在当前计数器不存在后新计数器淡入。
It probably happens because a new element with opacity 0 enters the dome and both values are displayed at the same time.
是的,就是这样。您可以使用 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;
}
我正在尝试熟悉 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;
}
我想实现以下行为:在 increment/decrement 当前显示的计数器逐渐消失,在当前计数器不存在后新计数器淡入。
It probably happens because a new element with opacity 0 enters the dome and both values are displayed at the same time.
是的,就是这样。您可以使用 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;
}