返回介绍

使用 ReactART library

发布于 2025-04-26 18:09:27 字数 9454 浏览 0 评论 0 收藏

在上一节,我们知道了怎么使用 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;

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。