- 内容简介
- 译者序
- 前言
- 第 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;
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论