原文連結 - https://github.com/AlloyTeam/omi/tree/master/tutorial
寫在前面
Omi框架正式釋出了omi-transform作為Omi元件化開發特效運動解決方案,讓你輕鬆在Omi專案裡快速簡便支援CSS3 Transform設定。先說說 transform.js (npm上的名字是 css3transform)。transform.js作為移動Web特效解決方案,在手Q興趣部落、日跡、QQ群、QQ附近等專案中廣泛使用,以激進的修改DOM屬性為代價,帶來極為便利的可程式設計性。
你可以通過alloyteam.github.io/AlloyTouch/…快速瞭解它。
上面官網的例子都是原聲js的,transformjs也擁有react版本,你也可以在react中以宣告式的方式使用transformjs:
render() {
return (
<Transform
translateX={100}
scaleX={0.5}
originX={0.5}>
<div>sth</div>
</Transform>
);
}複製程式碼
3分鐘掌握omi-transform
演示
alloyteam.github.io/omi/plugins…
通過npm安裝
npm install omi-transform複製程式碼
使用
import Omi from 'omi';
import OmiTransform from '../../omi-transform.js';
OmiTransform.init();
class App extends Omi.Component {
constructor(data) {
super(data);
}
installed(){
setInterval(function(){
this.refs.test.rotateZ += 0.1;
}.bind(this));
}
render() {
return `
<div omi-transform class="test" ref="test" rotateZ="45" translateX="100" perspective="400">
omi-transform
</div>
`;
}
}
Omi.render(new App(),"#container");複製程式碼
- 在需要使用transformjs的DOM上標記 omi-transform 和 ref="xxx"
- 在元件函式裡便可以使用 this.refs.xxx 來讀取或者設定 css transform屬性
- this.refs.xxx 支援 "translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ", "skewX", "skewY", "originX", "originY", "originZ", "perspective"這些屬性設定和讀取
- 沒有標記perspective的話程式碼沒有透視投影
效能對比
因為react版本會有diff過程,然後apply diff to dom的過程,state改變不會整個innerHTML全部替換,所以對瀏覽器渲染來說還是很便宜,但是在js裡diff的過程的耗時還是需要去profiles一把,如果耗時嚴重,不在webworker裡跑還是會卡住UI執行緒導致卡頓,互動延緩等。所以要看一看CPU的耗時還是很有必要的。
下面資料是對比omi-transform和react-transform,兩種方式使用chrome profiles了一把。
先看總耗時對比:
react-transform:
omi-transform:
- react在8739秒內CPU耗時花費了近似1686ms
- Omi方式在9254ms秒內CPU耗時花費近似700ms
在不進行profiles就能想象到react是一定會更慢一些,因為state的改變要走把react生命週期走一遍,但是可以看到react的耗時還是在可以接受的範圍,沒有慢到難以接受。
而Omi的方式則和傳統的原生js的耗時一模一樣。以為運動過程不進行DOMI Diff!!
慢著?不進行Diff?意思就是元件不進行update?
意思就是萬一元件update,所有運動的狀態都會丟失?Omi怎麼解決這個問題?
狀態儲存
元件裡的某個DOM在運動過程中,可能會由於其他邏輯,進行update。有可能是使用者互動,有可能是資料返回的回撥。所以,update前後,DOM的狀態的保留顯得尤其重要,不然的話就會有閃爍、跳躍的效果或者其他顯示邏輯錯誤。
...
constructor(data) {
super(data);
//初始狀態
this.rotateZ = 45;
}
installed(){
setInterval(() =>{
//sync for update 記錄同步到this.rotateZ
this.rotateZ = this.refs.test.rotateZ += 0.1;
});
}
render() {
//通過 ${this.rotateZ} 設定rotateZ
return `
<div omi-transform class="test" ref="test" rotateZ="${this.rotateZ}" translateX="100" perspective="400" >
omi-transform
</div>
`;
}
...複製程式碼
上面的所有例子和程式碼可以在這裡找到。
Omi相關
- Omi官網omijs.org
- Omi的Github地址github.com/AlloyTeam/o…
- 如果想體驗一下Omi框架,可以訪問 Omi Playground
- 如果想使用Omi框架或者開發完善Omi框架,可以訪問 Omi使用文件
- 如果你想獲得更佳的閱讀體驗,可以訪問 Docs Website
- 如果你懶得搭建專案腳手架,可以試試 omi-cli
- 如果你有Omi相關的問題可以 New issue
- 如果想更加方便的交流關於Omi的一切可以加入QQ的Omi交流群(256426170)