在React中,我们怎么样使用它跟CSS 3 动画结合在一起使用呢?
CSS3 Transitoin
CSS3动画要求DOM属性变化的时候才能够被触发。所以这就需要我们把属性变化后的React元素渲染到真实的DOM中,这样才能够有过渡效果,形成动画。
那我们来实现一种:第一次渲染后,当渲染完成时,调用setState(),且重新设置样式,接着便触发第二次渲染,中间便有过渡效果。
注意:使用window.getComputedStyle(),调用它,会刷新DOM的样式,确保的是之前设置的样式已经渲染到DOM中。
如下例子:
我们实现由图1到图2的过渡动画,代码如下
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>动画 : CSS3 Transition</title> 6 <script src="lib/react.min.js"></script> 7 <script src="lib/JSXTransformer.js"></script> 8 <!--组件样式--> 9 <style> 10 .ez-gauge{ 11 position:relative; 12 display:inline-block; 13 } 14 .ez-gauge .pointer{ 15 position : absolute; 16 left : 149px; 17 top : 104px; 18 transform-origin : 1px 45px; 19 transition : transform 2s; 20 } 21 </style> 22 </head> 23 <body> 24 <div id="content"></div> 25 <script type = "text/jsx"> 26 //组件定义 27 var EzGaugeComp = React.createClass({ 28 //声明初始状态 29 getInitialState : function(){ 30 return { 31 value : 0, //速度值 32 mounted : false //是否已挂接到DOM 33 }; 34 }, 35 //首次渲染后改变状态 36 componentDidMount : function(){ 37 this.setState({mounted : true}); 38 }, 39 //校验属性值,无效时不刷新界面 40 shouldComponentUpdate : function(nextProps,nextState){ 41 if(nextProps.value > 220 || nextProps.value<0) return false; 42 return true; 43 }, 44 render : function(){ 45 //速度为0时的旋转角度 46 var degree = -201; 47 //根据属性值计算旋转角度 48 if(this.state.mounted){ 49 degree = (this.props.value / 220) * 265 - 201; 50 //确保之前设置的样式生效 51 window.getComputedStyle(React.findDOMNode(this.refs.ptr)).transform; 52 } 53 //表针样式 54 var style={ 55 transform : "rotate("+degree+"deg)" 56 }; 57 return ( 58 <div className="ez-gauge"> 59 <img src="img/gauge.jpg" /> 60 <img src="img/gauge-pointer.jpg" className="pointer" style={style} ref="ptr"/> 61 </div> 62 ); 63 } 64 }); 65 //渲染 66 React.render( 67 <EzGaugeComp value="200"/>, 68 document.querySelector("#content")); 69 </script> 70 </body> 71 </html>
再提一次,window.getComputedStyle()是更新样式
默认属性
比如我们的React组件渲染了很多个,而如果我们为每一个都要设置value:0的属性,那么需要重复去声明,太麻烦了。
那React也为我们提供了组件的默认属性。
在声明组件的时候,用getDefaultProps()方法声明:(类比getInitialState吧)
1 var EzDemoComp = React.createClass({ 2 //设置默认属性值 3 getDefaultProps:function(){ 4 return { 5 value : 0 6 } 7 }, 8 render: function(){ 9 //使用this.props.value访问属性,如果用户没有设置,则该值为默认值 10 return <div classname="ez-demo">{this.props.value}</div>; 11 } 12 }); 13 //创建React元素时没有指定属性值 14 React.render(<ezdemocomp></ezdemocomp>, 15 document.querySelector("#content"));
当然,如果我们在render中的<ezdemocomp>中声明了value,则会覆盖默认属性,如<ezdemocomp value="1"></ezdemocomp>