transformjs在非react领域用得风生水起,那么react技术栈的同窗能用上吗?答案是能够的。junexie童鞋已经造了个react版本。css
传统 web 动画的两种方式:html
对应在react中:前端
使用CSS3html5
纯粹JS控制时间轴node
这里很明显,方案1和方案2可应对简单场景(如没有prop change 回调等),方案3可编程性最大,最灵活,能够适合复杂的动画场景或者承受复杂的交互场景。react
npm install css3transform-react复制代码
//set "translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ", "skewX", "skewY", "originX", "originY", "originZ"
render() {
return (
<Transform translateX={100} scaleX={0.5} originX={0.5}> <div>sth</div> </Transform>
);
}
// you can also use other porps, such as "className" or "style"
render() {
return (
<Transform translateX={100} className="ani" style={{width: '100px', background: 'red'}} <div>sth</div> </Transform>
);
}复制代码
经过上面的声明,就能够设置或者读取"translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ", "skewX", "skewY", "originX", "originY", "originZ"!css3
方便吧!git
import React, { Component } from 'react';
import { render } from 'react-dom';
import Transform from '../../transform.react.js';
class Root extends Component {
constructor(props, context) {
super(props, context);
this.state = {
el1: {rotateZ: 0},
el2: {rotateY: 0}
};
this.animate = this.animate.bind(this);
}
animate() {
this.setState({
el1: {rotateZ: this.state.el1.rotateZ + 1},
el2: {rotateY: this.state.el2.rotateY + 1}
}, () => {
requestAnimationFrame(this.animate);
});
}
componentDidMount() {
setTimeout(this.animate, 500);
}
render() {
return (
<div> <Transform rotateZ={this.state.el1.rotateZ} className="test" style={{'backgroundColor': 'green'}}> transformjs </Transform> <Transform rotateY={this.state.el2.rotateY} className="test" style={{'backgroundColor': 'red', 'left': '200px'}}> transformjs </Transform> </div>
);
}
}
render(
<Root />, document.getElementById('root') );复制代码
更加复杂的详细的使用代码能够看这里:github.com/AlloyTeam/A…github
alloyteam.github.io/AlloyTouch/…web
由于react版本会有diff过程,而后apply diff to dom的过程,state改变不会整个innerHTML所有替换,因此对浏览器渲染来讲仍是很便宜,可是在js里diff的过程的耗时仍是须要去profiles一把,若是耗时严重,不在webworker里跑仍是会卡住UI线程致使卡顿,交互延缓等。因此要看一看CPU的耗时仍是颇有必要的。
主要是那上面的演示和传统的直接操做dom的方式对比。就是下面这种传统的方式:
var element1 = document.querySelector("#test1");
Transform(element1);
...
...
function animate() {
element1.rotateZ++;
...
requestAnimationFrame(animate);
}
animate();复制代码
对两种方式使用chrome profiles了一把。
先看总耗时对比:
react:
传统方式:
在不进行profiles就能想象到react是必定会更慢一些,由于state的改变要走把react生命周期走一遍,可是能够看到react的耗时仍是在能够接受的范围。可是,咱们仍是但愿找到拖慢的函数来。
那么在使用transformjs react版本中,哪一个函数拖了后腿?展开profiles tree能够看到:
就是它了。
/** * Reconciles the properties by detecting differences in property values and * updating the DOM as necessary. This function is probably the single most * critical path for performance optimization. * * TODO: Benchmark whether checking for changed values in memory actually * improves performance (especially statically positioned elements). * TODO: Benchmark the effects of putting this at the top since 99% of props * do not change for a given reconciliation. * TODO: Benchmark areas that can be improved with caching. * * @private * @param {object} lastProps * @param {object} nextProps * @param {?DOMElement} node */
_updateDOMProperties: function (lastProps, nextProps, transaction) {复制代码
打开对应的代码能够看到。注释里已经写了这是优化重点。
官方网站:alloyteam.github.io/AlloyTouch/…
Github地址:github.com/AlloyTeam/A…
任何问题和意见欢迎new issue给咱们。AlloyTeam大量招前端,有梦想爱学习的你请把简历发送至 mhtml5@qq.com 。