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 。