native react 折线图_React-Native ART绘图

这篇博客介绍了如何在React-Native中利用ART库进行图形绘制,包括直线、虚线、矩形、三角形、多边形、多边线、圆形、半圆、扇形、圆环以及渐变色的绘制方法,并提供了详细的代码示例。同时,还讲解了如何使用图片填充绘制的形状和剪辑图形的概念。
摘要由CSDN通过智能技术生成

绘制 直线

绘制 虚线

绘制 矩形

绘制 三角形

绘制 多边形

绘制 多边线

绘制 圆形

绘制 半圆

绘制 扇形

绘制 圆环

绘制 渐变色

图片填充绘制的形状(Pattern)

props

Pattern

使用图片填充

Surface

width : 渲染区域的宽

height : 定义渲染区域的高

Shape

d : 定义绘制路径 (Path对象)

stroke : 描边颜色

strokeWidth : 描边宽度

strokeDash : 定义虚线

fill : 填充颜色

Path

moveTo(x,y) : 移动到坐标(x,y),设置初始点

lineTo(x,y) : 连线到(x,y)

Path().moveTo(20, 20).lineTo(10, 20) 得到的是一条(20, 20) 到(10, 20) 的线。

image.png

line(x,y): 相对于原来的偏移

Path().moveTo(20, 20).line(10, 20) 得到的是一条(20, 20) 到(30, 40) 的线。

image.png

arc() : 绘制弧线

Path().moveTo(150,50).arc(50, 100,50) 绘制一半圆弧(150,50)起点,(50, 100)偏移量(终点) 50 半径

image.png

Path().arc(30, 50, 70, 90, true, false, 1) 画一段圆弧(30, 50)起点,(70, 90)控制点 (true, false, 1)不知/逆时针/不知,另个一圆弧的点在视图的边缘

image.png

close() : 封闭空间

使用

import {

ART

} from 'react-native';

var {

Surface, // 一个矩形可渲染的区域,是其他元素的容器

Group, // 可容纳多个形状、文本和其他的分组

Shape, // 形状定义,可填充

Path, // 路径

LinearGradient, // 渐变色

Pattern, // 填充图片

ClippingRectangle, // 剪辑

} = ART;

直接使用SVG

.svg 路径的文件用浏览器打开,一片空白是正常的,右键查看网页源代码,找到path字段

var HEART_SVG = "M130.4-0.8c25.4 0 46 20.6 46 46.1 0 13.1-5.5 24.9-14.2 33.3L88 153.6 12.5 77.3c-7.9-8.3-12.8-19.6-12.8-31.9 0-25.5 20.6-46.1 46-46.2 19.1 0 35.5 11.7 42.4 28.4C94.9 11 111.3-0.8 130.4-0.8"

svg代码

绘制 直线

{/*绘制 直线*/}

let zhixian_path = Path()

.moveTo(0,5) // 改变起点为 0,5 。默认为0,0

.lineTo(300,5) // 目标点

黄色中间的直线

绘制 虚线

{/*绘制 虚线*/}

let xuxian_path = Path()

.moveTo(0,5) // 改变起点为 0,5 。默认为0,0

.lineTo(300,5) // 目标点

let xuxian_path1 = Path()

.moveTo(0,15) // 改变起点为 0,15 。默认为0,0

.lineTo(300,15) // 目标点

{/*strokeDash={[5,20] 先是5像素的实线,再是20像素的空白,再是5像素的实线... 循环*/}

{/*strokeDash={[10,5,20,5] 先是10像素的实线,再是5像素的空白,再是20像素的实线, 再是5像素的空白... 循环*/}

黄色中间两条虚线

绘制 矩形

let juxing_path = Path()

.moveTo(5,5)

.lineTo(295,5)

.lineTo(295,25)

.lineTo(5,25)

.close() // close 封闭

{/*绘制 矩形*/}

黄色中间矩形

绘制 三角形

let sanjiaoxing_path = Path()

.moveTo(100,5)

.lineTo(200, 25)

.lineTo(30,10)

.close()

{/*绘制 三角形*/}

黄色中间三角形

绘制 多边形

let duobianxing_path = Path()

.moveTo(50, 10)

.lineTo(80, 0)

.lineTo(120, 60)

.lineTo(60, 90)

.lineTo(10, 30)

.lineTo(80, 70)

.close()

{/*绘制 多边形*/}

黄色内部

绘制 多边线

let duobianxian_path = Path()

.moveTo(50, 10)

.lineTo(80, 0)

.lineTo(120, 60)

.lineTo(60, 90)

.lineTo(10, 30)

.lineTo(80, 70)

.close()

{/*绘制 多边线*/}

黄色内部

绘制 圆形、半圆

// 正常情况下 arc()只用来画圆,想要花圆弧使用...

// 实际是由两条 圆弧 构成了一个圆(左右两半拼成一个圆)

let yuanxing_path = Path()

.moveTo(50, 0)// 起点位置

.arc(0,100,50) // 将 (50,0) 看成新的坐标系(0,0),由此进行 顺时针(100正) 的画半弧。

.arc(0,-100,50) // 将 (0,100) 看成新的坐标系(0,0),由此进行 逆时针(-100负) 的画半弧。

.close() // arc第一个参数为 0 是因为 终点的x和原点在一条直线上,确保画的是半圆弧

// arc 第一个参数不为0 的情况

let yuanxing_path2 = Path()

.moveTo(150,50)

.arc(50, 100,50) // 给定了终点的坐标,即可自动算出半径,第三个参数 的范围预估 不可大于 真正的半径 不可小于1

.close()

let yuanxing_path3 = Path()

.moveTo(100,120)

.arc(-50, 100,50) // 给定了终点的坐标,即可自动算出半径,第三个参数 的范围预估 不可大于 真正的半径 不可小于1

.close()

let yuanxing_path4 = Path().moveTo(50, 5)// 起点位置

.arc(0, 100, 50) // 将起点位置看成新的坐标系,(50, 5)为新的原点(0,0)。100为正值,顺时针方向画半圆,50 为半径,100为终点坐标

.arc(0, 80, 40) // 将(0,100)看成新的坐标系(0,0),80为正值,顺时针方向画半圆,40 为半径,80为终点坐标

.arc(0, 60, 30) // 将(0, 80)看成新的坐标系(0,0),60为正值,顺时针方向画半圆,30 为半径,60为终点坐标

.arc(0, -20, 10) // 将(0, 60)看成新的坐标系(0,0),20为负值,逆时针方向画半圆,10 为半径,-20为终点坐标

.close();

{/*绘制 圆形*/}

黄色内部

扇形、圆环

需要一个绘制类

import React, { Component } from 'react';

import { ART } from 'react-native';

const { Shape, Path } = ART;

import PropTypes from 'prop-types'

/**

* Wedge is a React component for drawing circles, wedges and arcs. Like other

* ReactART components, it must be used in a .

*/

export default class Wedge extends Component {

constructor(props : any) {

super(props);

(this:any).circleRadians = Math.PI * 2;

(this:any).radiansPerDegree = Math.PI / 180;

(this:any)._degreesToRadians = this._degreesToRadians.bind(this);

}

/**

* _degreesToRadians(degrees)

*

* Helper function to convert degrees to radians

*

* @param {number} degrees

* @return {number}

*/

_degreesToRadians(degrees : number) : number {

if (degrees !== 0 && degrees % 360 === 0) { // 360, 720, etc.

return (this:any).circleRadians;

}

return degrees * (this:any).radiansPerDegree % (this:any).circleRadians;

}

/**

* _createCirclePath(or, ir)

*

* Creates the ReactART Path for a complete circle.

*

* @param {number} or The outer radius of the circle

* @param {number} ir The inner radius, greater than zero for a ring

* @return {object}

*/

_createCirclePath(originX : number, originY : number, or : number, ir : number) : Path {

const path = new Path();

path.move(originX, or + originY)

.arc(or * 2, 0, or)

.arc(-or * 2, 0, or);

if (ir) {

path.move(or - ir, 0)

.counterArc(ir * 2, 0, ir)

.counterArc(-ir * 2, 0, ir);

}

path.close();

return path;

}

/**

* _createArcPath(sa, ea, ca, or, ir)

*

* Creates the ReactART Path for an arc or wedge.

*

* @param {number} startAngle The starting degrees relative to 12 o'clock

* @param {number} endAngle The ending degrees relative to 12 o'clock

* @param {number} or The outer radius in pixels

* @param {number} ir The inner radius in pixels, greater than zero for an arc

* @return {object}

*/

_createArcPath(originX : number, originY : number, startAngle : number, endAngle : number, or : number, ir : number) : Path {

const path = new Path();

// angles in radians

const sa = this._degreesToRadians(startAngle);

const ea = this._degreesToRadians(endAngle);

// central arc angle in radians

const ca = sa > ea ? (this:any).circleRadians - sa + ea : ea - sa;

// cached sine and cosine values

const ss = Math.sin(sa);

const es = Math.sin(ea);

const sc = Math.cos(sa);

const ec = Math.cos(ea);

// cached differences

const ds = es - ss;

const dc = ec - sc;

const dr = ir - or;

// if the angle is over pi radians (180 degrees)

// we will need to let the drawing method know.

const large = ca > Math.PI;

// TODO (sema) Please improve theses comments to make the math

// more understandable.

//

// Formula for a point on a circle at a specific angle with a center

// at (0, 0):

// x = radius * Math.sin(radians)

// y = radius * Math.cos(radians)

//

// For our starting point, we offset the formula using the outer

// radius because our origin is at (top, left).

// In typical web layout fashion, we are drawing in quadrant IV

// (a.k.a. Southeast) where x is positive and y is negative.

//

// The arguments for path.arc and path.counterArc used below are:

// (endX, endY, radiusX, radiusY, largeAngle)

path.move(originX, originY) // move to starting point

.arc(or * ds, or * -dc, or, or, large) // outer arc

.line(dr * es, dr * -ec); // width of arc or wedge

if (ir) {

path.counterArc(ir * -ds, ir * dc, ir, ir, large); // inner arc

}

return path;

}

render() : any {

// angles are provided in degrees

const startAngle = this.props.startAngle;

const endAngle = this.props.endAngle;

// if (startAngle - endAngle === 0) {

// return null;

// }

// radii are provided in pixels

const innerRadius = this.props.innerRadius || 0;

const outerRadius = this.props.outerRadius;

const { originX, originY } = this.props;

// sorted radii

const ir = Math.min(innerRadius, outerRadius);

const or = Math.max(innerRadius, outerRadius);

let path;

if (endAngle >= startAngle + 360) {

path = this._createCirclePath(originX, originY, or, ir);

} else {

path = this._createArcPath(originX, originY, startAngle, endAngle, or, ir);

}

return ;

}

}

Wedge.propTypes = {

outerRadius: PropTypes.number.isRequired, // 圆弧半径

startAngle: PropTypes.number.isRequired, // 开始角度

endAngle: PropTypes.number.isRequired, // 结束角度

originX: PropTypes.number, // 左边的距离 不是圆心的X

originY: PropTypes.number, // 上部的距离 不是圆心的Y

innerRadius: PropTypes.number, //内部半径 用户画弧

}

Wedge.defaultProps = {

originX: 0,

originY: 0,

}

使用

outerRadius={100}

startAngle={0}

endAngle={160}

originX={80}

originY={50}

fill="blue" />

outerRadius={100}

innerRadius={90}

startAngle={0}

endAngle={40}

originX={80}

originY={50}

fill="purple" />

黄色内部

渐变色

// .5 颜色占比表示 50%, 那个颜色的占比大,在前;颜色比小,在后。不能大于1

// 同样的占比,后面的会把前面的替换掉

// 必须是 Int 类型, 不可以是float或其他

// x1,y1,x2,y2 x1,y1颜色的起点;x2,y2颜色的终点

// "0", "0", "300", "0" 300为组件的宽度、弧度的长度 此:表示 横向颜色渐变

// "0", "0", "0", "40" 40为组件的高度、弧度的高度 此:表示 纵向颜色渐变

// "0", "0", "300", "100" 300、100 渐变是横向 ///(渐变样式犹如斜杠) 渐变

var linearGradient = new LinearGradient({

'.4': 'green',

'.6': 'blue',

},

"0", "0", "300", "100"

);

outerRadius={100}

innerRadius={90}

startAngle={0}

endAngle={100}

originX={80}

originY={50}

fill={linearGradient}/>

image.png

图片填充绘制的形状(Pattern)

(resolveAssetSource(本地图片) 得到本地图片的url

let url = resolveAssetSource(require('./image.png'))

image.png

import resolveAssetSource from 'resolveAssetSource'

const pattern = new Pattern(resolveAssetSource(pengyouImage),90,90,5,5)

image.png

ClippingRectangle 剪切绘制的图形

width={ 100 } //要剪辑的宽

height={ 50 } //要剪辑的高

x={ 40 } //要剪辑的left

y={ 0 }> //要剪辑的top

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值