博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初窥基于 react-art 库的 React Native SVG
阅读量:5752 次
发布时间:2019-06-18

本文共 4635 字,大约阅读时间需要 15 分钟。

技术背景

在移动应用的开发过程中,绘制基本的二维图形或动画是必不可少的。然而,考虑到Android和iOS均有一套各自的API方案,因此采用一种更普遍接受的技术方案,更有利于代码的双平台兼容。

是一个旨在多浏览器兼容的Node style CommonJS模块。在它的基础上,Facebook又开发了 ,封装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: 。React.js和React-Native的区别,只在于下文所述的ART获取上,然后该例子就可以同时应用在Web端和移动端上了。

成功运行Vector-Widget后的效果图:

图片描述

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 (        
);}

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 
}

可以看到,取出的Path是一个构造函数。Path对象的中的函数功能如下,大多与svg规范一致,我就再啰嗦一遍了。svg规范中<path>的d属性请参见 :

  • 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: 在缩放的同时保持原来的长宽比。例子和效果图如下:

图片描述

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

效果如下图所示:

图片描述
图片描述

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开发和维护的引入的,react-native依赖了fbjs,而所有需要被输出的js文件的头部都会以// @providesModule Circle.art

的形式标明。

Circle

使用示例:

值得一提的是,Circle.art.js是个半成品,可以看到它根本没有实现svg规范中的cx和cy,因此画出来的圆的圆心始终在左上角,显示出来的也就只有半个圆。请在实际应用中自行实现,或者使用笔者提供的。

当然,不用cx和cy的话,也可以设置tranform来实现平移。如:

两种方法都可以达到平移效果,但是cx, cy的方式相对来说更简洁,可读性也更好。

Rectangle

使用示例:

使用上述代码,就很直观看到这个module的缺陷了,矩形四条边不等宽(扶额)。

图片描述
此外还接受的props有:

  • radius

  • radiusTopLeft

  • radiusTopRight

  • radiusBottomLeft

  • radiusBottomRight

这里的radius指的是圆角矩形的圆角半径,接受的值类型为数字,radius为四个角的通用半径,但如果设置了具体某个角的半径,则用后者。

Wedge

Wedge是楔子的意思,然而在这里却是生成各种角度的扇形=_=。

使用示例:

生成的图形如下图:

图片描述
可选Props为innerRadius,用于生成一个圆环扇形,如下图。
图片描述
呐,一看这个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

转载地址:http://zcukx.baihongyu.com/

你可能感兴趣的文章
TCP&UDP压力测试工具
查看>>
oracle 导入数据
查看>>
首个5G智慧机场落地广州 速度是4G的50倍
查看>>
Android 最简单的自定义Dialog之一
查看>>
磨刀不误砍柴 - 配置适合工作学习的桌面环境
查看>>
自己动手写docker-3
查看>>
Java笔记-反射机制(一)
查看>>
redux v3.7.2源码解读与学习之 applyMiddleware
查看>>
【React】为什么我不再使用setState?
查看>>
Git原理与高级使用(3)
查看>>
从JDK源码看Writer
查看>>
Express 结合 Webpack 实现HMRwi
查看>>
SQL模糊查询通配符_和%处理
查看>>
ssl免费申请
查看>>
我的友情链接
查看>>
基于protobuf的RPC实现
查看>>
ehcache 常用参数
查看>>
坚信每个人都能成为品牌
查看>>
Java语言的基础知识3
查看>>
JAVA的对象复制
查看>>