初窥基于 react-art 库的 React Native SVG

手艺背景

在挪动运用的开辟过程当中,绘制基础的二维图形或动画是必不可少的。然则,考虑到Android和iOS均有一套各自的API计划,因而采纳一种更广泛接收的手艺计划,更有利于代码的双平台兼容。

art是一个旨在多浏览器兼容的Node style CommonJS模块。在它的基础上,Facebook又开辟了react-art ,封装art,使之能够被react.js所运用,即完成了前端的svg库。然则,考虑到react.js的JSX语法,已支撑将<cirle> <svg>等等svg标签直接插入到dom中(固然此时运用的就不是react-art库了)另外另有HTML canvas的存在,因而,在前端上,react-art并不是不可替换。

然则,在挪动端,考虑到跨平台的需求,加上web端的手艺积聚,react-art成为了现成的绘制图形的解决计划。react-native离别在0.10.0和0.18.0上添加了iOS和Android平台上对react-art的支撑,固然,没有文档。在文档基础即是没有的状况下,笔者苦逼地翻源代码,为人人带来了(环球首发?=_=)的入门文档。

示例代码

引荐人人采纳react-art自带的Example: Vector-Widget。React.js和React-Native的区分,只在于下文所述的ART猎取上,然后该例子就能够同时运用在Web端和挪动端上了。

胜利运转Vector-Widget后的结果图:
《初窥基于 react-art 库的 React Native SVG》

Vector-Widget分外完成了扭转,以及鼠标点击事宜的扭转加快相应。Web端能够看到点击加快,然则在挪动端无效,原因是React Native并未对Group中onMouseDown和onMouseUp属性作处置惩罚。本文着重于静态svg的完成,临时疏忽动画部份结果即可。

另外还能够用该例子感受一下蔚为大观svg动画的机能占用(摊手)。

道理和挪用

猎取ART

package.json中须要引入art库,笔者的版本设置是react-art: 0.14.0

Android与iOS

var React = require('react-native');
var ReactART = React.ART;

或许运用ES6的Destructuring特征:

var {
    ...,
    ART,
    ...,
} = React;

Web端

var React = require('react');
var ReactART = React.ART;

基础组件

猎取体式格局

接下来的所述的代码,web端和挪动端都是通用的,这也是React Native的引诱地点。

var {
    Shape,
    Group,
    Transform,
    Surface,
    ...,
} = React.ART;

Surface

一切的svg component必需被一个Surface标签所包括。
Props以下:

  • width: Surface的宽度。

  • height: Surface的高度。

  • style: margin系列和padding系列都见效。

Group

Group用于组合art component。比如在一个函数中返回多个svg component的状况,此时就必需要用<Group>包一下,不然即报错。<Group>能够嵌套运用。

style:margin和padding系列均无效,我疑心不接收style。

function _render() {
    return (
        <Group>
            <Shape d={"M160 160 A 45 45, 0, 0, 1, 115 205"} stroke="#000000" strokeWidth={3} />
            <Shape d={"M160 160 A 45 45, 0, 0, 1, 115 205"} stroke="#000000" strokeWidth={3} />
        </Group>
    );
}

Shape

Shape用于天生途径,语法与svg中的<path>很类似。Shape的Props以下:

  • d: 语法与svg范例雷同

  • stroke: 线条色彩,”#FFFFFF”的情势

  • strokeWidth: 线条宽度,{3}的情势

  • transform:接收 new ART.Transform()天生的object,详细见下文Transform条目。

Path

语法更近似于挪动端。运用要领:

var ReactART = require('./ReactART');
var Path = ReactART.Path;

function _render() {
    // 除close之外的一切要领都返回修正后的本身,因而支撑链式挪用
    var path = Path().moveTo(0, -radius)
       .arc(0, radius * 2, radius)
       .arc(0, radius * -2, radius)
       .close();
       
    // path能够直接赋值给d
    return <Shape d={path} />
}

能够看到,掏出的Path是一个组织函数。Path对象的中的函数功用以下,大多与svg范例一致,我就再烦琐一遍了。svg范例中<path>的d属性请拜见https://developer.mozilla.org/en-US/docs…

  • push():

  • reset(): 清空Path

  • move(x, y): 等同于’m’,挪动到目标坐标,参数x和y是相对目标下的目标坐标

  • moveTo(x, y): 等同于’M’,与move只差异在x和y是相对坐标。

  • line(x, y): 等同于’l’,从一个坐标点到另一个坐标点画直线,参数x和y是相对坐标下的目标坐标

  • lineTo(x, y): 等同于’L’,与line只差异在x和y是相对坐标。

  • arc(x, y, rx, ry, outer): 等同于’a’,从一个坐标点向另一个坐标点画椭圆曲线,x和y是相对坐标下的目标坐标,rx和ry是椭圆的长轴半径和短轴半径,outer只要0和1两个数字,代表是大角度照样小角度。

  • arcTo(x, y, rx, ry, outer): 等同于’A’,与arc只差异在x和y是相对坐标。

  • curve(2个,4个或6个参数): 从一个坐标点向另一个坐标点画贝塞尔曲线。

    • 当参数为两个时,等同于’t’,绘制润滑二次贝塞尔曲线。

    • 当参数为4个时,等同于’q’,绘制二次贝塞尔曲线。

    • 当参数为6个时,等同于’c’,绘制三次贝塞尔曲线。

    • 有些通晓SVG的同砚这时候能够就要问我了,不对啊,二次贝塞尔曲线和润滑三次贝塞尔曲线的参数都是4个,你这里没有润滑三次啊?由于开辟的同砚留坑没写了呀(笑容)。

Transform

完成代码途径:art/core/transform.js

Transform对象中的函数:

  • transform(xx, yx, xy, yy, x, y): transform的相对坐标版本

  • transformTo: 完全的矩阵变更,把这张位图上一切的点都做一次矩阵乘法,获得的新位图,公式以下图所示$$ \begin{Bmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \\ \end{Bmatrix} \times \begin{Bmatrix} x \\ y \\ 1 \end{Bmatrix}$$

  • translate(x, y): 位移

  • move: 相对于原参考点坐标,增减参考点的x,y坐标

  • moveTo: 等同于translateTo,轻易误以为是move的相对左侧版本,吐糟不能

  • scale(x, y): 将一个元素拉伸或许紧缩指定的倍数,x是宽度缩放比例,y是长度缩放比例,假如只要一个参数,则x = y。如

  • scaleTo: 在缩放的同时对峙本来的长宽比。例子和结果图以下:

<Surface
  width={700}
  height={700}>
  <Rectangle
      width={100}
      height={200}
      stroke="red"
      strokeWidth={10}
      fill="FFFFFF"
      transform={new Transform().translate(150, 150).scale(2)}
  />
  <Rectangle
      width={100}
      height={200}
      stroke="yellow"
      strokeWidth={10}
      fill="FFFFFF"
      transform={new Transform().translate(150, 150).scaleTo(1, 2)}
  />
  <Rectangle
      width={100}
      height={200}
      stroke="blue"
      strokeWidth={10}
      fill="FFFFFF"
      transform={new Transform().translate(150, 150)}
  />
</Surface>

《初窥基于 react-art 库的 React Native SVG》

  • rotate(deg, x, y): 将一个元素扭转角度deg。x和y则是用于指定扭转的原点。

<Surface
  width={700}
  height={700}>
  <Rectangle
      width={100}
      height={200}
      stroke="red"
      strokeWidth={10}
      fill="FFFFFF"
      transform={new Transform().translate(150, 150)}
  />
  <Rectangle
      width={100}
      height={200}
      stroke="red"
      strokeWidth={10}
      fill="FFFFFF"
      transform={new Transform().translate(150, 150).rotate(30, 100, 100)}
  />
</Surface>
<Surface
    width={700}
    height={700}>
    <Rectangle
        width={100}
        height={200}
        stroke="red"
        strokeWidth={10}
        fill="FFFFFF"
        transform={new Transform().translate(150, 150)}
    />
    <Rectangle
        width={100}
        height={200}
        stroke="red"
        strokeWidth={10}
        fill="FFFFFF"
        // 差异在这里
        transform={new Transform().translate(150, 150).rotate(30)}
    />
</Surface>

结果以下图所示:
《初窥基于 react-art 库的 React Native SVG》
《初窥基于 react-art 库的 React Native SVG》

react-art中的lib

引入lib中的module

在react-art的库中,有个奇异的lib文件夹,下面除了ReactART.js之外,另有Circle.art.js,Rectangle.art.js,Wedge.art.js等,个中Circle和Rectangle离别对应于svg范例中的圆形<circle>,矩形<rect>,而Wedge则是用于天生扇形。固然,这些module都很不完善,很有能够须要二次开辟,假如如许,引荐拷贝库文件到工程中再行修正。

引入它们的语句为var Circle = require('react-art/lib/Circle.art');。这类不同寻常地援用体式格局是Facebook开辟和保护的fbjs引入的,react-native依靠了fbjs,而一切须要被输出的js文件的头部都邑以// @providesModule Circle.art
的情势标明。

Circle

运用示例:

<Circle
    radius={10}
    stroke="green"
    strokeWidth={3}
    fill="blue"
/>

值得一提的是,Circle.art.js是个半成品,能够看到它基础没有完成svg范例中的cx和cy,因而画出来的圆的圆心一直在左上角,显示出来的也就只要半个圆。请在现实运用中自行完成,或许运用笔者供应的修正版本

固然,不必cx和cy的话,也能够设置tranform来完成平移。如:

<Circle
    radius={10}
    stroke="green"
    strokeWidth={3}
    fill="blue"
    transform={new Transform().translate(100, 100)}
/>

两种要领都能够到达平移结果,然则cx, cy的体式格局相对来说更简约,可读性也更好。

Rectangle

运用示例:

<Rectangle
  width={200}
  height={400}
  stroke="red"
  strokeWidth={10}
  fill="FFFFFF"
/>

运用上述代码,就很直观看到这个module的缺点了,矩形四条边不等宽(扶额)。
《初窥基于 react-art 库的 React Native SVG》
另外还接收的props有:

  • radius

  • radiusTopLeft

  • radiusTopRight

  • radiusBottomLeft

  • radiusBottomRight

这里的radius指的是圆角矩形的圆角半径,接收的值范例为数字,radius为四个角的通用半径,但假如设置了详细某个角的半径,则用后者。

Wedge

Wedge是楔子的意义,然则在这里倒是天生种种角度的扇形=_=。
运用示例:

<Wedge
  outerRadius={50}
  stroke="red"
  startAngle={0}
  endAngle={100}
  fill="FFFFFF"
/>

天生的图形以下图:
《初窥基于 react-art 库的 React Native SVG》
可选Props为innerRadius,用于天生一个圆环扇形,以下图。
《初窥基于 react-art 库的 React Native SVG》
呐,一看这个module也是半成品,假如stroke有色彩而fill为白色就露馅了,曲线没闭合。因而,若有需求,请自行填补。

手艺缺点

除了之前所提到的林林总总的完成上的不完善之外,svg范例在React Native上运用的最大问题在于,有一大批web上的svg支撑的css属性,还没有在React Native上完成。

以stroke类的一大批属性为例,现在可用的只要线条色彩stroke和strokeWidth,而如stroke-dasharray,stroke-dashoffset如许的能够用之完成奇异的描边等结果的CSS属性,现在还没有被支撑。

在机能占用方面, 静态svg尚可接收,但假如是svg annimation,实测红米Note 2上的CPU占用率即可达50%摆布,故其在临盆环境的大规模运用,生怕还需进一步的机能优化。

====================================
假如您以为我的文章对您有所启示,请点击文末的引荐按钮,您的勉励将会成为我对峙写作的莫大鼓励。 by DesGemini

    原文作者:DesGemini
    原文地址: https://segmentfault.com/a/1190000004422456
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞