在React Native中使用ART
React Native ART 究竟是什么?
所谓ART,是一个在React中绘制矢量图形的JS类库。这个类库抽象了一系统的通用接口,统一了SVG,canvas,VML这类矢量图形在React中的书写格式。你可以通过ART将SVG,canvas,VML的矢量图形拿到React中使用,也可以把ART反转回去。(虽然有很多局限性,后面会讲到)React Native ART 是react-art在React Native中的移植版,接口几乎完全一致,React Native中的ART很早之前就已经开源了iOS版,最近又在0.18.0中开源了Android版本因为缺少官方文档,一直不为人所知。
为什么要在React Native中使用 ART?
我在前端页面切片的时候比较喜欢用SVG,有条件我都尽量让设计师出AI的设计稿或者把图标导成SVG的因为SVG和图片相比,优点太多太多:可以代码复用,可以无损放大,通过合理导出的svg代码比同等压缩过的图片文件大小要小很多,而且svg代码还可以通过gzip压缩最近在做一个原生内嵌的React Native项目,设计师是按照原生APP的标准把每个图标切了3个尺寸给我,感谢React Native中强大的打包工具,可以很方便的使用这写图标。所以项目开始也没想着要用SVG(当时android的ART还没开源,这也是一个重要因素)。在整个项目完成之后,看了一下,所有图片在经过压缩之后加起来有200多K,大小还可以接受。但是在项目后期优化过程中,发现一个使用图片图标非常致命的问题:
的多个Image也不能在同一帧里面渲染出来的,如下的5个图标,在iOS下它们不会同时被渲染出来,这样造成的影响是在打开一个列表的时候,看见这些图标一个接一个无序的跳出来,这个效果如果在iphone4s,5s下看相当的明显,很恶心,完全不能忍受!想过各种方法也没办法绕过去。
首屏的如下几个图标以及返回按钮和logo,还有TabBar里面的图标在iOS下都是在界面出现的若干帧之后再无序的跳出来,这样的效果很不好,一点都没有原生APP的感觉,有一种hybird的既视感。
后来等到了0.18.0,Android的ART对外开源了,我想到为什么不用SVG图标尝试一下呢?然后让设计师把这个图标:
这里面的路径代码是通过PS CC直接导出的,没有做任何优化,如果再优化一番可以再缩小一半。SVG代码优化后面再做介绍。下面正式进入正题
如何在React Native中使用 ART?
安装 ART
安装ART很简单安卓里面根本不用安装,0.18.0里面自带,直接在js引入既可
import React, {ART} from 'react-native';const {Surface, Group, Shape} = ART;
iOS里面的ART是可选的,你需要手动导入xcodeproj文件,以及加入静态链接库但是也很简单:教程
使用ART
请大家原谅我,其实我是标题党,我不会在这里详细的讲解ART的用法,而是讲一个基于ART的SVG库:react-native-art-svg
为什么我不在这里讲ART呢?原因如下上面那段代码是ART代码和设计师给我svg代码其实有一些差异,还要把SVG转换一次,很不友好,因为ART的元素和SVG元素名称和用法都不太一样在SVG代码里面,画布元素是
安装很简单,因为是纯JavaScript的类库,直接一行搞定npm i react-native-art-svg --save
通过如下代码在js中引入
import Svg, { Circle, Ellipse, G, LinearGradient, RadialGradient, Line, Path, Polygon, Polyline, Rect, Symbol, Text, Use, Defs, Stop} from 'react-native-art-svg';
上面的ART代码等同于如下的代码
这段代码从SVG转过来可省心多了,只需要改一下元素的大小写,把元素名称改成大写字母开头的既可,属性名称改成驼峰式的命名方式。
通用属性列表:
属性名称
默认值
描述
fill
'#000'
内部填充规则(填充颜色,填充渐变图形)
fillOpacity
1
填充的透明度
stroke
'none'
描边颜色
strokeWidth
1
描边的宽度
strokeOpacity
1
描边的透明度
strokeLinecap
'square'
描边线段端点显示方式
strokeLinejoin
'miter'
描边线段连接处的显示方式
strokeDasharray
[]
描边线段断点显示规则
x
0
当前图形x轴偏移量
y
0
当前图形y轴偏移量
rotate
0
当前图形旋转值
scale
1
当前图形的缩放值
origin
0, 0
变形原点(x,y,rotate,scale的变形原点坐标)
originX
0
变形原点x轴坐标
originY
0
变形原点y轴坐标
可以看到,几乎所有SVG的常用属性都可以支持不支持fillRule,因为官方认为fillRule不是SVG,canvas和VML公用的属性,他们不对这类独有的属性进行支持暂不支持clipPath,因为ART官方还未完成
支持的元素列表:
Svg
Svg为所有矢量图形的画布元素,所有Svg内的矢量图形都会绘制在Svg内部并且Svg支持viewbox和preserveAspectRatio属性(关于这两个属性的详解)
;
上面的代码会绘制如下的图形
其中height和width定义了Svg元素的宽高注意在react-native-art-svg中,所有元素的数字类型的属性都可以直接用字符串表示,如:下面两段属性声明都可以正常使用,这样写起来很方便height="100"
height={100}
矩形:Rect
上面的代码绘制了一个左上角位于画布25,5,宽150,高50的矩形并且使用蓝色(rgb(0,0,255))填充(fill)内部背景用黑色(rgb(0,0,0))进行描边(stroke),描边宽度(strokeWidth)为3
圆型:Circle
椭圆:Ellipse
直线:Line
多边形:Polygon
多边线:Polyline
路径:Path
属性内定义了一系列的路径坐标以及绘制规则命令,上面的所有图形都可以通过Path绘制而成
M = 把绘制点移动到某个位置
L = 从当前绘制点画一条直线到某个坐标
H = 从当前绘制点沿着x轴水平画线
V = 从当前绘制点沿着y轴垂直画线
C = 从当前绘制点画一条曲线到某个坐标
S = 从当前绘制点画一条平滑的曲线到某个坐标
Q = 从当前绘制点画一条贝赛尔曲线到某个坐标
T = 从当前绘制点画一条平滑的贝赛尔曲线到某个坐标
A = 从当前绘制点画一条椭圆曲线到某个点
Z = 闭合当前路径
注意: 上面所有的命令都可以使用小写字母,大写字母的命令是使用的坐标是绝对值,小写字母的命令的坐标是相对值
文字:Text
SVG进阶元素使用
分组:G
下面两段代是相同的
G元素的变形属性不会被继承
定义:Defs
复用:Use
使用