- 内容简介
- 译者序
- 前言
- 第 1 章 安装配置新项目
- 第 2 章 Flexbox 布局介绍
- 第 3 章 用 React Native 开发一个应用
- 第 4 章 在 React Native 中使用导航
- 第 5 章 动画和滑动菜单
- 第 6 章 用 React Native 绘制 Canvas
- 第 7 章 使用 React Native 播放音频
- 第 8 章 你的第一个自定义视图
- 第 9 章 Flux 介绍
- 第 10 章 处理复杂的应用程序状态
- 第 11 章 使用 Node 来实现服务端 API
- 第 12 章 在 React Native 中使用文件上传
- 第 13 章 理解 JavaScript Promise
- 第 14 章 fetch 简介
- 第 15 章 在 iOS 中使用 SQLite
- 第 16 章 集成 Google Admob
- 第 17 章 React Native 组件国际化
- 附录 A React.js 快速介绍
- 附录 B Objective-C Primer
- 附录 C webpack 入门
使用 ReactART library
在上一节,我们知道了怎么使用 WebView 组件来渲染 Canvas。在这一节,我们将使用 ReactART library 来渲染原生的 Canvas,不再用 WebView 了。
首先,我们需要知道怎么在网页上使用 ReactART。了解了它的 API,你就可以将它移植到 React Native 平台了。
在网页中使用 ReactART
让我们使用 npm 创建一个项目,命令行代码如下:
mkdir reactarttest cd reactartest npm install -g webpack npm init
我们安装 webpack 作为打包工具。关于 webpack 的更多信息请参考本书的附录 C。
创建 webpack.config.js 文件:
var webpack = require('webpack');
modules.exports = {
content: __dirname,
entry: './app.js',
module: {
loaders: [
{
test: /\.js$/,
loader: 'jsx-loader'
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {NODE_ENV: JSON.stringify('production')}
})
]
};
下面是 package.json 的内容,你需要复制并粘贴到你的项目中。
{
"name": "art",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"postinstall": "npm install ../..",
"build": "webpack app.js bundle.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"jsx-loader": "^0.13.2",
"node-libs-browser": "^0.5.2",
"react": "^0.13.3",
"react-art": "^0.13.0",
"webpack": "^1.9.10"
}
}
运行下面的命令安装依赖模块:
npm install
为了创建项目,在命令行输入如下命令:
npm run build
这个命令将会通过 app.js 这个项目的入口文件生成 bundle.js。
接着,创建 index.html 文件:
<! DOCTYPE html> <html> <head> <title>Demo React Art</title> </head> <body> <div id="content"></div> <script src="bundle.js"></script> </body> </html>
下面是我们的入口文件 app.js:
"use strict";
var React = require('react');
var DemoWidget = require('./DemoWidget');
React.render(<DemoWidget /> , document.getElementById('content'));
DemoWidget 组件简单地渲染出 Hello World 文字。
"use strict";
var React = require('react');
var ReactART = require('react-art');
var Surface = ReactART.Surface;
var Text = ReactART.Text;
var DemoWidget = React.createClass({
render: function(){
return (
<Surface x={300} y={300} width={1000} height={1000} style
={{cursor: 'pointer'}}>
<Text fill="#A6BD8A" font='bold 60px "Arial"'>Hello World
</Text>
</Surface>
)
}
});
module.exports = DemoWidget;
结果如下图:

在 React Native 中使用 ReactART
首先让我们创建一个 React Native 项目(这里假设你已经安装了 React Native cli)。使用 react-native init React_Art_Demo 命令,因为通过 npm 安装的 React Native 中不包含 ART lib,所以我们要在 node_modules 目录中删除 react-native 文件夹,然后在 github 上克隆一个新的版本。
我们也需要自己安装 ART lib,所以进入到 React_Art_Demo 项目的根目录。运行 npm install art 命令。
一但我们检出了 react-native 的 master 分支,并且 art 已经安装完毕,我们就可以在 XCode 中打开 React_Art_Demo 项目。
我们需要做两件事情:
1.将 ART.xcodeproj 文件添加到 Xcode 中。
2.链接二进制库。
将位于 react-native/Libraries/ART/下的 ART.xcodeproj 文件拖到 Xcode 中的 Libraries 目录下,如下图所示那样。

当左边的 React_Art_Demo 项目是选中的,从中间的视图选择 Build Phases,然后会出现一个名为 Link Binary With Libraries 的目录,展开它,按“+”号选择 libART.a。如下图所示:

现在开始编写你的 react-art 代码,为此我通常会先将 vector-widget 例子运行通过,代码如下:
index.ios.js
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var VectorWidget = require('./VectorWidget');
var react_art_demo = React.createClass({
render: function() {
return (
<View style={styles.container}>
<VectorWidget style={styles.vector}/>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
backgroundColor: '#FFF',
},
vector: {
width: 100,
height: 100
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
color: '#333333',
marginBottom: 5,
marginTop: 100
},
});
AppRegistry.registerComponent('react_art_demo', () =>
react_art_demo);
VectorWidget.js
"use strict";
var React = require('react-native');
var ReactArt = require('./node_modules/react-native/Libraries/ART/
ReactNativeART');
var {
Art,
TouchableWithoutFeedback
} = React;
var {
Group,
Shape,
Surface,
Transform
} = ReactArt;
var MOUSE_UP_DRAG = 0.978;
var MOUSE_DOWN_DRAG = 0.9;
var MAX_VEL = 11;
var CLICK_ACCEL = 3;
var BASE_VEL = 0.15;
/**
* 一个
SVG 动画组件
*/
var VectorWidget = React.createClass({
/**
* 初始化状态成员
*/
getInitialState: function() {
return {degrees: 0, velocity: 0, drag: MOUSE_UP_DRAG};
},
/**
* 当组件被加载进文档,它相当于一个构造器,但是当实例真正地被加载进文档才会
* 被调用。这里我们创建一个动画循环调用我们的方法。
'this.onTick’是不需要
* 绑定的,因为所有
React 方法都是自动绑定在加载之前。
*/
componentDidMount: function() {
this._interval = window.setInterval(this.onTick, 20);
},
componentWillUnmount: function() {
window.clearInterval(this._interval);
},
onTick: function() {
var nextDegrees = this.state.degrees + BASE_VEL + this.state.
velocity;
var nextVelocity = this.state.velocity * this.state.drag;
this.setState({degrees: nextDegrees, velocity: nextVelocity});
},
/**
* 这是所有组件的主要方法,
React API 允许在任何时候将这段代码添加到你的
UI
* 组件。
*/
render: function() {
return (
<Surface width={700} height={700} style={{cursor: 'pointer
'}}>{this.renderGraphic(this.state.degrees)}</Surface>
);
},
/**
* React 即将对
SVG 更好地支持
*/
renderGraphic: function(rotation) {
return (
<Group>
<Group x={210} y={135}>
<Shape fill="rgba(0,0,0,0.1)" d={BORDER_PATH} />
<Shape fill="#7BC7BA" d={BAR_PATH} />
<Shape fill="#DCDCDC" d={RED_DOT_PATH} />
<Shape fill="#D97B76" d={YELLOW_DOT_PATH} />
<Shape fill="#DBBB79" d={YELLOW_DOT_PATH} />
<Shape fill="#A6BD8A" d={GREEN_DOT_PATH} />
<Group x={55} y={29}>
<Group rotation={rotation} originX={84} originY={89}>
<Shape fill="#FFFFFF" d={CENTER_DOT_PATH} />
<Group>
<Shape d={RING_ONE_PATH} stroke="#FFFFFF"
strokeWidth={8} />
<Shape d={RING_TWO_PATH} transform={RING_TWO_ROTATE
} stroke="#FFFFFF" strokeWidth={8} />
<Shape d={RING_THREE_PATH} transform={
RING_THREE_ROTATE} stroke="#FFFFFF" strokeWidth
={8} />
</Group>
</Group>
</Group>
</Group>
</Group>
);
}
});
var BORDER_PATH = "M3.00191459,4 C1.34400294,4 0,5.34785514
0,7.00550479 L0,220.994495 C0,222.65439 1.34239483,224
3.00191459,224 L276.998085,224 C278.655997,224 280,222.652145
280,220.994495 L280,7.00550479 C280,5.34561033 278.657605,4
276.998085,4 L3.00191459,4 Z M3.00191459,4";
var BG_PATH = "M3.00191459,1 C1.34400294,1 0,2.34785514
0,4.00550479 L0,217.994495 C0,219.65439 1.34239483,221
3.00191459,221 L276.998085,221 C278.655997,221 280,219.652145
280,217.994495 L280,4.00550479 C280,2.34561033 278.657605,1
276.998085,1 L3.00191459,1 Z M3.00191459,1";
var BAR_PATH = "M3.00191459,0 C1.34400294,0 0,1.34559019
0,3.00878799 L0,21 C0,21 0,21 0,21 L280,21 C280,21 280,21 280,21
L280,3.00878799 C280,1.34708027 278.657605,0 276.998085,0 L3
.00191459,0 Z M3.00191459,0";
var RED_DOT_PATH = "M12.5,17 C16.0898511,17 19,14.0898511 19,10.5
C19,6.91014895 16.0898511,4 12.5,4 C8.91014895,4 6,6.91014895
6,10.5 C6,14.0898511 8.91014895,17 12.5,17 Z M12.5,17";
var YELLOW_DOT_PATH = "M31.5,17 C35.0898511,17 38,14.0898511
38,10.5 C38,6.91014895 35.0898511,4 31.5,4 C27.9101489,4
25,6.91014895 25,10.5 C25,14.0898511 27.9101489,17 31.5,17 Z M31
.5,17";
var GREEN_DOT_PATH = "M50.5,17 C54.0898511,17 57,14.0898511 57,10.5
C57,6.91014895 54.0898511,4 50.5,4 C46.9101489,4 44,6.91014895
44,10.5 C44,14.0898511 46.9101489,17 50.5,17 Z M50.5,17";
var CENTER_DOT_PATH = "M84,105 C92.8365564,105 100,97.8365564
100,89 C100,80.1634436 92.8365564,73 84,73 C75.1634436,73
68,80.1634436 68,89 C68,97.8365564 75.1634436,105 84,105 Z M84
,105";
var RING_ONE_PATH = "M84,121 C130.391921,121 168,106.673113 168,89
C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871
0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121";
var RING_TWO_PATH = "M84,121 C130.391921,121 168,106.673113 168,89
C168,71.3268871 130.391921,57 84,57 C37.6080787,57 0,71.3268871
0,89 C0,106.673113 37.6080787,121 84,121 Z M84,121";
var RING_THREE_PATH = "M84,121 C130.391921,121 168,106.673113
168,89 C168,71.3268871 130.391921,57 84,57 C37.6080787,57
0,71.3268871 0,89 C0,106.673113 37.6080787,121 84,121 Z M84
,121";
var RING_TWO_ROTATE = new Transform().translate(84.000000,
89.000000).rotate(-240.000000).translate(-84.000000, -89.000000)
;
var RING_THREE_ROTATE = new Transform().translate(84.000000,
89.000000).rotate(-300.000000).translate(-84.000000, -89.000000)
;
module.exports = VectorWidget;
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论