基于道具来回样式组件动画
styled-components animation back and forth based on props
我想让我的主要内容在特定道具上滑入和滑回
所以我创建了动画,我想我会在道具改变的情况下添加反向。
现在下面的代码可以工作了,但唯一的问题是在第一页加载时我可以看到 "slideOutContent" 动画
我不希望它发生,这些幻灯片只有在侧边栏打开时才会发生,然后它会滑动内容。
const slideInContent = keyframes`
from {
margin-left: 0;
}
to {
margin-left: 256px;
}
`;
const slideOutContent = keyframes`
from {
margin-left: 256px;
}
to {
margin-left: 0;
}
`;
// Here we create a component that will rotate everything we pass in over two seconds
const MainContentBox = styled.div`
animation: ${props => props.slide ? `${slideInContent} forwards` : `${slideOutContent}`};
animation-duration: 0.5s;
animation-timing-function: linear;
`;
这就是我使用这个组件的方式:
class PageWithDrawer ... {
constructor(props) {
super(props);
this.state = {
open: false
};
}
toggleMenu() {
this.setState(state => {
return { open: !state.open };
});
}
render() {
....other stuff
<MainContentBox slide={this.state.open}>
{this.props.children}
</MainContentBox>
....other stuff
}
目前您正在给 MainContentBox
一个布尔值,但您有三个条件:SLIDE_IN、SLIDE_OUT 和 NO_SLIDE 条件。
为了避免第一次渲染时使用额外的布尔标志,您可以state.open
在其他语言中称为 Enum 的东西 - 这三个值中的任何一个的持有者。
// You can put these in a named {} for encapsulation
const NO_SLIDE = 0, SLIDE_OUT = 1, SLIDE_IN = 2;
class PageWithDrawer ... {
constructor(props) {
super(props);
this.state = {
open: NO_SLIDE, // Initial state
};
}
toggleMenu() {
this.setState(state => ({ open: state.open % 2 + 1 }));
}
state % 2 + 1
是0→1、1→2、2→1的转换公式
现在让我们将状态变量映射到动画 属性 字符串:
const stateToAnimation = {
NO_SLIDE: 'none',
SLIDE_OUT: slideInContent + ' forwards',
SLIDE_IN: slideOutContent,
}
const MainContentBox = styled.div`
animation: ${props => ${stateToAnimation[props.slide]}};
`; // other props...
您可能还需要用 ${}
将 props.slide
括起来,我不确定这种语法。
也许只需使用 transition
而不是 animation
。在这个特定的示例中,它应该可以完成这项工作,但我不确定它是否总是可行的。
我想让我的主要内容在特定道具上滑入和滑回
所以我创建了动画,我想我会在道具改变的情况下添加反向。
现在下面的代码可以工作了,但唯一的问题是在第一页加载时我可以看到 "slideOutContent" 动画
我不希望它发生,这些幻灯片只有在侧边栏打开时才会发生,然后它会滑动内容。
const slideInContent = keyframes`
from {
margin-left: 0;
}
to {
margin-left: 256px;
}
`;
const slideOutContent = keyframes`
from {
margin-left: 256px;
}
to {
margin-left: 0;
}
`;
// Here we create a component that will rotate everything we pass in over two seconds
const MainContentBox = styled.div`
animation: ${props => props.slide ? `${slideInContent} forwards` : `${slideOutContent}`};
animation-duration: 0.5s;
animation-timing-function: linear;
`;
这就是我使用这个组件的方式:
class PageWithDrawer ... {
constructor(props) {
super(props);
this.state = {
open: false
};
}
toggleMenu() {
this.setState(state => {
return { open: !state.open };
});
}
render() {
....other stuff
<MainContentBox slide={this.state.open}>
{this.props.children}
</MainContentBox>
....other stuff
}
目前您正在给 MainContentBox
一个布尔值,但您有三个条件:SLIDE_IN、SLIDE_OUT 和 NO_SLIDE 条件。
为了避免第一次渲染时使用额外的布尔标志,您可以state.open
在其他语言中称为 Enum 的东西 - 这三个值中的任何一个的持有者。
// You can put these in a named {} for encapsulation
const NO_SLIDE = 0, SLIDE_OUT = 1, SLIDE_IN = 2;
class PageWithDrawer ... {
constructor(props) {
super(props);
this.state = {
open: NO_SLIDE, // Initial state
};
}
toggleMenu() {
this.setState(state => ({ open: state.open % 2 + 1 }));
}
state % 2 + 1
是0→1、1→2、2→1的转换公式
现在让我们将状态变量映射到动画 属性 字符串:
const stateToAnimation = {
NO_SLIDE: 'none',
SLIDE_OUT: slideInContent + ' forwards',
SLIDE_IN: slideOutContent,
}
const MainContentBox = styled.div`
animation: ${props => ${stateToAnimation[props.slide]}};
`; // other props...
您可能还需要用 ${}
将 props.slide
括起来,我不确定这种语法。
也许只需使用 transition
而不是 animation
。在这个特定的示例中,它应该可以完成这项工作,但我不确定它是否总是可行的。