Base on react-motion by Chenglou, write a tab animate demo and try to explain how to think and dismantling animation elements.
1.Clone this repo.
2.Modify something in package.json like name to .
3.Run npm install.
$ npm install
4.Run development server.
$ npm run dev
5.Open your browser to http://localhost:8001/
Because the game named Clash Royale Recently I play, I think it's funny, thanks to supercell.
First, look the animation again and again, carefully. And try to find those points can be partitioned animation.
Two tab and one slide mask block, a pair of title, icon, indicator. And find that three steps in animation.
- Mouse down(Touch start), the size of icon who has selected in smaller. And Mouse up(Touch end) revert to the original size.
- If selected tab changed, moving mask block, and the animation duration in easing.
- If selected tab changed, the width of block who has selected in bigger, and others width in smaller. The same to icon. The last, show or hide title and indicator.
But something interesting here, hmmm, style z-index in react is not supported by now :P (As in react-native, CSS style transform-origin is not supported to change...OH NO)
So we need to make sure title, icon on the top layer, at least topper than mask block.
Okay, done it!
render: function() {
var windowWidth = window.innerWidth;
return (
<div>
{ this.state.selectedTab === 1 ? <Tab1 /> : <Tab2 /> }
<Motion style={{
s1: spring((this.state.isPressed && this.state.selectedTab === 1) ? 1.4 : (this.state.selectedTab === 1 ? 1.8 : 1.4)),
s2: spring((this.state.isPressed && this.state.selectedTab === 2) ? 1.4 : (this.state.selectedTab === 2 ? 1.8 : 1.4)),
a1: spring(this.state.selectedTab === 1 ? 1 : 0),
a2: spring(this.state.selectedTab === 2 ? 1 : 0),
w1: spring(this.state.selectedTab === 1 ? windowWidth * 2/3 : windowWidth * 1/3),
w2: spring(this.state.selectedTab === 2 ? windowWidth * 2/3 : windowWidth * 1/3),
l2: spring(this.state.selectedTab === 1 ? windowWidth * 2/3 : windowWidth * 1/3),
left: spring(this.state.selectedTab === 1 ? 0 : windowWidth * 1/3, {stiffness: 206, damping: 12}),
swing: spring(this.state.swing ? 30 : 40, {stiffness: 320, damping: 2})
}}>
{({ s1, s2, a1, a2, w1, w2, l2, left, swing }) =>
<Row type="flex" justify="center" align="middle" style={{
position: 'fixed',
bottom: 0,
width: '100%',
height: 69,
textAlign: 'center',
padding: 0,
backgroundColor: '#FFF',
borderTop: `2px solid #45566A` }}>
<div style={{
position: 'absolute',
top: 1,
width: windowWidth * 2/3,
height: 69,
left: left,
backgroundColor: 'rgba(92,144,177,0.5)',
opacity: 1 }}>
</div>
<div onMouseDown={this.handleMouseDown.bind(this, 1)} onTouchStart={this.handleTouchStart.bind(this, 1)}
onMouseUp={this.handleMouseUp}
onTouchEnd={this.handleMouseUp}
style={{
position: 'absolute',
top: 1,
width: w1,
height: 69,
left: 0,
backgroundColor: 'transparent',
borderRight: `2px solid #45566A` }}>
<img src="./static/img/caret-r.png"
style={{
position: 'absolute',
top: 20,
width: 15,
height: 20,
right: swing,
opacity: a1 }} />
<img src="./static/img/power.png"
style={{
width: 30,
height: 30,
marginTop: this.state.selectedTab !== 1 ? 16 : 0,
WebkitTransform: `scale(${s1})`,
transform: `scale(${s1})` }} />
<p style={{
marginTop: 6,
fontSize: 16,
fontWeight: 900,
color: '#535353',
opacity: a1 }}> 标签页1 </p>
</div>
<div onMouseDown={this.handleMouseDown.bind(this, 2)} onTouchStart={this.handleTouchStart.bind(this, 2)}
onMouseUp={this.handleMouseUp}
onTouchEnd={this.handleMouseUp}
style={{
position: 'absolute',
top: 1,
width: w2,
height: 69,
left: l2,
backgroundColor: 'transparent',
borderLeft: `2px solid #9AB4C8` }}>
<img src="./static/img/caret-l.png"
style={{
position: 'absolute',
top: 20,
width: 15,
height: 20,
left: swing,
opacity: a2 }} />
<img src="./static/img/info.png"
style={{
width: 30,
height: 30,
marginTop: this.state.selectedTab !== 2 ? 16 : 0,
WebkitTransform: `scale(${s2})`,
transform: `scale(${s2})` }} />
<p style={{
marginTop: 6,
fontSize: 16,
fontWeight: 900,
color: '#535353',
opacity: a2 }}> 标签页2 </p>
</div>
</Row>
}
</Motion>
</div>
);
},
Don't forget clear those timer when component unmount.
Careful observation, discover, you can make it.
I hope that can help you, thank you ;)
My Blog yuzhouisme.com.
Tome, help students to remember words tome.yuzhouisme.com.