React Native ART绘制图形

一、前言

我们知道在Html5,Android,iOS中都提供了绘制相关的API,如Html5中的canvas标签,Android中的Canvas类,iOS中的CoreGraphics,这些API都可以实现丰富的图形绘制;因为在实际移动应用的开发过程中,使用系统提供的一些UI组件可能没办法做出我们想要的UI效果,这个时候就需要使用绘制相关的API来自定义绘制复杂的UI;

在React中react-art是reactjs团队基于art(一个兼容各个浏览器SVG绘制的API封装)开发的模块,让react开发者能使用jsx语法绘制svg。
React Native团队分别在0.10.0和0.18.0也添加了iOS和Android平台对react-art的支持在低版本的React Native中ART就在React Native内核中,我们可以直接使ART,在高版本 的React Native中ART移动到了 '@react-native-community/art’中了,我们需要引入art库;

二、React Native ART

-React Native ART到底可以干什么?

React Native ART 是用来绘制矢量图(SVG)的;他可以让我们像Android中Canavs一样简单的绘制任意UI;

-React Native ART使用

在安卓中使用无需配置任何东西就可使用,在iOS中ART是可选的,你需要手动导入ART.xcodeproj文件,并手动导入libART.a静态库。
iOS项目中配置ART的具体方式如下:
在Xcode选中项目点击右键->Add Files to Your Project Name->选择添加Project path/node_modules/react-native/Libraries/ART/ART.xcodeproj。
在Build Phases中的Link Binary With Libraries中点击+号,选择添加libART.a。

-React Native ART使用步骤

(1)在低版本的React Native中ART就在React Native内核中,我们可以直接使用ART;

使用方式:在使用的时候直接导入相关组件

 import {
    ART
  } from 'react-native'

  const {
    Surface,
    Shape,
    Path,
    Tranform
} = ART 

(2)在高版本的React Native中ART从React Native 核心库中移除了,被移到了@react-native-community/art中,

使用:

-引入art库

 npm install  @react-native-community/art

-使用的时候导入相关组件

import {Surface, Shape,Path} from '@react-native-community/art';

-基本的API
(1)Surface 一个矩形可渲染的区域,是其他元素的容器!
所有的ART相关组件都必须在Surface中,Surface中不能有非ART组件;
并且Surface必须设置宽和高

  <Surface width={500} height={500} style={{backgroundColor:'#FFFFFF'}}>
         ...
  </Surface>     

(2)Shape 形状

可以设置的属性:

stroke: 线的颜色

fill:填充的颜色

strokeWidth:线的粗细

strokeDash:设置虚线相关 值是数组 数组中是两个元素第一个元素 是每个虚线的长度,第二个元素是虚线之间的距离

d:赋值一个Path对象,用于设置Shape显示的绘制形状

transform:赋值一个Transform对象,用于实现对形状的平移,旋转,缩放操作

(3)Path

Shape的属性值 表示绘制的路径

使用:

-创建Path对象

 let path=new Path();

-方法

moveTo(x,y): 移动到x,y (绝对坐标)

move(x,y): 横坐标移动x,纵坐标移动y

lineTo(x,y): 目标点坐标为(x,y) 绝对坐标,初始点和目标点之间连线

line(x,y): 目标点为当前点横坐标移动x,纵坐标移动y,初始点和目标点之间连直线

arc(x,y,rx,ry,outer): 目标点为横坐标移动x,纵坐标移动y,然后从初始点向目标点画
椭圆曲线,长轴半径为rx,短轴半径为ry

arcTo(x,y,rx,ry,outer): 目标点为(x,y)绝对坐标,然后从初始点向目标点画
椭圆曲线,长轴半径为rx,短轴半径为ry

curve(2个,4个或者6个参数):从一个坐标点向另一个坐标点画贝塞尔曲线
当参数为2个时,绘制光滑二次贝塞尔曲线;
当参数为4个时,绘制二次贝塞尔曲线;
当参数为6个时,绘制三次贝塞尔曲线;

(4)Transform
Shape的属性值,对绘制的内容变换的属性,包括,平移,旋转,缩放变换

-创建Transform对象

let tranform=new Transform()

-方法

translate(x,y): 横坐标方向移动x,纵坐标方向移动y

scale(x,y):宽缩放x,高缩放y倍小于1就是缩小,大于一就是放大

roate(deg,x,y):以(x,y)为旋转中心旋转deg度

(5)Group
Group组件可有可无,当绘制内容较多时可以用其统一管理,可以把它当做View标签使用,可制定内容在画布绘制的起点。

<Surface>
     <Group x={100} y={100}>
        <Shape
             strokeWidth={10}
             stroke={'#3366FF'}
             d={this.linePath}
             originX={DEVICE_WIDTH/2}
             originY={DEVICE_HEIGHT/2} />
     </Group>
 </Surface>  

-实例 (绘制直线,虚线,矩形,圆)

import React from 'react';
import {
    View,
    Dimensions
} from 'react-native';
import {Surface, Shape,Path,Transform} from '@react-native-community/art';

export let DEVICE_WIDTH = Dimensions.get('window').width;
export let DEVICE_HEIGHT = Dimensions.get('window').height;

export default class MainScreen extends React.Component{
  line = new Path().moveTo(0, DEVICE_HEIGHT / 2 - 200)
        .line(DEVICE_WIDTH, 0);

    dashLine = new Path().moveTo(0, DEVICE_HEIGHT / 2)
        .line(DEVICE_WIDTH, 0);

    rectPath = new Path()
        .moveTo(20, DEVICE_WIDTH / 2)
        .lineTo(100, DEVICE_WIDTH / 2)
        .lineTo(100, DEVICE_WIDTH / 2 + 100)
        .lineTo(20, DEVICE_WIDTH / 2 + 100)
        .close();

    circlePath = new Path().moveTo(0, DEVICE_HEIGHT / 2)
        .arc(DEVICE_WIDTH, 0, DEVICE_WIDTH / 2, DEVICE_WIDTH / 2, 0)
        .arc(-DEVICE_WIDTH, 0, DEVICE_WIDTH / 2, DEVICE_WIDTH / 2, 0)
    
         render(){
            return (

            <View>
                <Surface width={DEVICE_WIDTH} height={DEVICE_HEIGHT}>

                    {/* 实线 */}
                    <Shape
                        stroke={Color.colorBlue}
                        strokeWidth={5}
                        d={this.line}
                    />

                    {/* 虚线 */}
                    <Shape
                        stroke={Color.colorBlue}
                        strokeWidth={5}
                        d={this.dashLine}
                        strokeDash={[50, 100]}>
                    </Shape>
                    
                      {/* 矩形 */}
                    <Shape
                        stroke={Color.colorBlue}
                        strokeWidth={5}
                        d={this.rectPath }
                        >
                    </Shape>

 					{/* 圆*/}
                    <Shape
                        stroke={Color.colorBlue}
                        strokeWidth={5}
                        d={this.circlePath}
                        >
                    </Shape>
                </Surface>
            </View >
            )     
      }
}

以上就是使用ART来绘制一些基本的图形;

三、React Native ART 动画

上面介绍了使用ART 的一些API来绘制基本的图形,但是这些图形都是静态的,往往我们需要图形是有动画效果的,如绘制一个加载中的圆形进度条,也即一个不断旋转的圆 ;
前面我们已经学习过React Native 动画(Animated),所以可以结合React Native中提供的Animated API来使得ART绘制的内容动起来 ;

我们知道Animated默认只支持 Animated.View, Animated.Image,Animated.ScrollView, Animated.Text,Animated.FlatList,Animated.SectionList这几种组件;
但是我们可以使用Animated.createAnimatedComponent(组件)来使得任意组件支持Animated动画;

所以我们可以让ART中的Shape创建AnimatedShape来使得Shape可以使用Animated动画,也即可以让ART绘制的内容动起来;

const AnimatedShape=Animated.createAnimatedComponent(Shape);

然后使用AnimatedShape以及Shape的相关属性,以及Animated来实现ART动画

(1)平移 通过不断改变Shape的 x,y属性值来实现平移

移动的直线:

import React from 'react';
import {
    View,
    Dimensions
} from 'react-native';
import {Surface, Shape,Path,Transform} from '@react-native-community/art';
export let DEVICE_WIDTH = Dimensions.get('window').width;
export let DEVICE_HEIGHT = Dimensions.get('window').height;
export default class MainScreen extends React.Component{
   linePath=new Path().move(0,0).lineTo(100,100);
   animateX=Animated.Value(0)
   translateX=Animated.timing(this.animateX, {
        toValue: 100,          //属性目标值
        duration: 1000,       //动画执行时间
        easing: Easing.linear
    })
   componentDidMount() {
       this.translateX.start()
   }
   render(){
    
    return (
       <View>
        <Surface width={DEVICE_WIDTH} height={DEVICE_HEIGHT}>
             <AnimatedShape
                 strokeWidth={10}
                 stroke={'#3366FF'}
                 x={this.animateX}
                 y={this.animateX}
                 d={this.linePath}
              >
        </Surafce>
       </View>
    )
   }
}

(2)旋转
Shape的originX,originY属性为旋转中心,通过不断改变 rotation 旋转角度来实现旋转动画

旋转的圆形加载进度条:

import React from 'react';
import {
    View,
    Dimensions
} from 'react-native';
import {Surface, Shape,Path,Transform} from '@react-native-community/art';
export default class MainScreen extends React.Component{
    radius=30
    bgCirclePath=new Path().moveTo(DEVICE_WIDTH/2-this.radius,DEVICE_HEIGHT/2)
        .arc(this.radius*2,0,this.radius,0,0)
        .arc(-(this.radius*2),0,this.radius,0,0)

    progressCirclePath=new Path().moveTo(DEVICE_WIDTH/2- this.radius,DEVICE_HEIGHT/2)
        .arc(this.radius*2,0,this.radius,0,0)
    deg=new Animated.Value(0)    
    rotate=Animated.timing(this.deg, {
    toValue: 1,        //属性目标值
    duration: 1000,    //动画执行时间
    easing: Easing.linear
    })    
    
    componentDidMount() {
        this.startAnimate()
    }

    startAnimate(){
        this.deg.setValue(0)
        this.rotate.start(()=>{this.startAnimate()})
    }    
   render(){
    
    return (
       <View>
        <Surface width={DEVICE_WIDTH} height={DEVICE_HEIGHT}>
        
         <AnimatedShape
             strokeWidth={10}
             stroke={'#C0C0C0'}
             d={this.bgCirclePath}
             >
         </AnimatedShape>

     <AnimatedShape
         strokeWidth={10}
         stroke={'#0066FF'}
         d={this.progressCirclePath}
         rotation={realDeg}
         originX={DEVICE_WIDTH/2}
         originY={DEVICE_HEIGHT/2}>  
      </AnimatedShape>
     </Surafce>
   </View>
    )
   }
}

(3)缩放 通过修改Shape的scale或者scaleX,scaleY属性值来实现缩放
这个就不再写示例了,直接参考上面平移,旋转动画实现就可以了;

以上就是React Native ART 动画的基本实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值