0

Flipboard推出React Canvas

 6 months ago
source link: https://www.jdon.com/47104.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Flipboard推出React Canvas

Flipboard增加React组件渲染<canvas>,而不是DOM。该开源项目不少代码已经进入flipboard.com的生产阶段:Flipboard/react-canvas · GitHub

Facebook刚刚发布React.js是基于DOM渲染,通过算法计算虚拟DOM和实际物理DOM之间的差别,然后渲染差别达到快速性能。参考:使用React Native的第一印象,React.js单方向的数据流和声明API已经改变了人们构建应用的方式:flux模式

如果将React组件绑定到canvas布局(而不是DOM)会怎样呢?Flipboard进行了大胆尝试:

Flipboard已经有很长的构建面向移动设备的界面历史,他们发现移动应用相对原生应用感觉比较慢的是DOM,CSS动画和切换是在Web上最快速实现平滑动画的方式,但是它们有一些限制,而React Canvas考虑到大多数现代浏览器已经有硬件加速的canvas。

同时还有其他试图绑定Canvas绘图API实现React,它们更加注重在视觉效果和游戏。在构建不同用户界面上的重点不同导致React Canvas的差别,事实上,渲染到canvas是一个实现细节。

React Canvas给Web开发者带来熟悉的API,并带给他们一个高性能绘图引擎。

以使用Javascript实现页面滚动效果来说明,使用一个canvas元素实现滚动,当发生每个触摸事件时,当前渲染树被当前根据滚动偏移量计算的每个节点更新,整个渲染树然后重新使用新的坐标系渲染。这个过程会很慢,但是这里有一个重要的性能优化:可将绘图操作结果缓存在一个off-screen离屏canvas上,这个off-screen离屏canvas然后在稍后时间用来重画。

这种技术不但可用于图片层,文字和图形都可以,很费力的绘图操作是填充文字和图形图像,但是一旦等到这些层画完,能够使用off-screen离屏canvas快速重画它们。下图每个页面分为两个层,一个图片层和一个文字层,文字层包含很多组元素,在滚动动画的每一帧中,两个层使用缓存位图bitmap进行重画:

scrolling.gif

使用React Canvas的实现代码:

var ListView = React.createClass({
getInitialState: function () {
return {
scrollTop: 0
};
},

render: function () {
var items = this.getVisibleItemIndexes().map(this.renderItem);
return (
<Group
onTouchStart={this.handleTouchStart}
onTouchMove={this.handleTouchMove}
onTouchEnd={this.handleTouchEnd}
onTouchCancel={this.handleTouchEnd}>
{items}
</Group>
);
},

renderItem: function (itemIndex) {
// Wrap each item in a <Group> which is translated up/down based on
// the current scroll offset.
var translateY = (itemIndex * itemHeight) - this.state.scrollTop;
var style = { translateY: translateY };
return (
<Group style={style} key={itemIndex}>
<Item />
</Group>
);
},

getVisibleItemIndexes: function () {
// Compute the visible item indexes based on `this.state.scrollTop`.
}
});

触摸事件:

// Create the Scroller instance on mount.
componentDidMount: function () {
this.scroller = new Scroller(this.handleScroll);
},

// This is called by the Scroller at each scroll event.
handleScroll: function (left, top) {
this.setState({ scrollTop: top });
},

handleTouchStart: function (e) {
this.scroller.doTouchStart(e.touches, e.timeStamp);
},

handleTouchMove: function (e) {
e.preventDefault();
this.scroller.doTouchMove(e.touches, e.timeStamp, e.scale);
},

handleTouchEnd: function (e) {
this.scroller.doTouchEnd(e.timeStamp);
}

这么简单的代码体现了React的最好品质,触摸事件被声明地绑定在render()中,每个触摸事件转发到Scroller,在那里计算当前滚动距离顶部的偏移差值,从Scroller发出的每个滚动事件更新ListView组件的状态,只是更新屏幕上可见部分,所有这些在16毫秒内发生,因为React的比较算法非常快。

React Canvas相比iOS/Andriod原生应用的优点,比如原生应用中不能从应用程序中复制一段文本,或者复制一个链接到浏览器,复制电话号码或地址。而基于DOM/Canvas能做到这些。

[该贴被banq于2015-02-11 17:13修改过]


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK