SVG和Canvas绘图(一)

SVG和Canvas绘图(一),第1张

栅格图形 ,也叫做点阵图,位图(bitmap),像素图,图像是由像素构成的,像素的多少将决定图像的显示质量和文件大小,图像的分辨率越高,其显示越清晰,文件所占的空间也就越大。图像放大时会失真,可以看到整个图像是由很多像素组合而成的。

矢量图形 使用 XML 来描述二维图形和绘图程序,矢量图像在放大或改变尺寸的情况下其图形质量不会有所损失。

<canvas>和<svg>都是HTML5推荐使用的图形技术,Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,只能通过脚本绘制图形;SVG为矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,本身就能独立使用,也可以嵌入到HTML中,SVG很早就成为了国际标准,目前的稳定版本是11 – Scalable Vector Graphics (SVG) 11 (Second Edition) ,两者的主要特点见下面的表格:

SVG

Canvas

图形和图表
svg和Canvas都可以表现图表(如柱状图, 散点图, 饼图等等),常用的图形图表库中,百度的echarts是基于Canvas实现的,D3是基于svg实现的。

xmlns属性可定义SVG 命名空间(如果将SVG内嵌在HTML页面中并作为该页面提供,则不需要xmlns属性)。

使用 <g> 元素,可以对多个元素进行分组

path元素是SVG基本形状中功能最强大的一个,它不仅能创建其他基本形状,还能创建更多其他形状。你可以用path元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2次曲线等。
path元素的形状是通过属性d来定义的,属性d的值是一个“命令+参数”的序列。

下面的命令可用于路径数据:(命令详情可查看 >下面是Canvas类常用的方法

drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF一个区域

drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint 画刷对象。

drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

drawText(String text, float x, floaty, Paint paint) //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

drawOval(RectF oval, Paint paint)//画椭圆,参数一是扫描区域,参数二为paint对象;

drawCircle(float cx, float cy, float radius,Paint paint)// 绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象;

Canvas是画布的意思,就是画画的布
那个bitmap没有必要 实例化一个Paint 在canvasdrawText() canvasdeawLine();用来绘制线和文本
如果用bitmap就是绘制对应的图,或者我们可以理解为贴图,就是绘制一个和bitmap一样的图出来
Canvas需要几个要素,一个是绘制的图的图(bitmap或者其他不用传入bitmap的方法),而一个绘制图的笔(point)

在实际的开发当中,我们经常会涉及到绘制路径,这里我们总结一下 Path 的常用 API 。

对于一个 Path 来说,它其中有很多的”子路径“,对于每个”子路径“,它又会有两个变量,"源点"和"当前点",也就是源码当中所描述的:

下面是 Path 当中和连线相关的方法:

每次调用完 moveTo/rMoveTo 方法,都会生成一条新的子路径,这两者的区别在于:
1 新建一条路径, (x, y) 作为这个新路径的“源点"的值,在图上不会产生新的连线。
2 相对于当前路径的"当前点"的值,移动坐标 (dx, dy) ,作为新路径的"源点",在图上不会产生新的连线。

1 从当前点位置,直线连接到绝对坐标 (x, y) ,如果没有调用过 moveTo/rMoveTo ,那么会先调用 moveTo(0, 0) 来生成一条从源点开始的子路径。
2 相对于当前点坐标,移动 (dx, dy) 作为终点坐标,并连接起点和终点。

1 从当前点位置开始,以 (x1, y1) 为控制点,按一阶贝塞尔曲线计算方法连接到 (x2, y2) ,如果之前没有调用过 moveTo/rMoveTo ,也会先调用一次 moveTo(0, 0) 方法。
2 类似于上面,只不过终点坐标是相对于当前点坐标移动了 (dx2, dy2) 后的值。

和一阶贝塞尔曲线类似,不过是多了一个控制点 (x2, y2) 。

上面这三个函数,最终都是调用了同一个方法:

它的原理就是:首先根据 RectF 或者 4 个点的坐标来确定一个矩形区域,之后得到这个矩形的内切椭圆,然后再根据 startAngle 和 sweepAngle 来确定这个内切源的一段弧,这段弧就是新绘制的路径。但是这段弧的起点很有可能和 Path 的当前点不是重合的,这时候就根据 forceMoveTo 来决定是否产生一条新的子路径,从最终的结果看,就是是否需要绘制一条从 Path 当前点到这段弧起点的连线,如果为 forceMoveTo=false ,那么就绘制这么一条直线,反之,则不绘制, forceMoveTo 的默认值为 false 。
forceMoveTo=false

forceMoveTo=true

forceMoveTo=true + pathclose()

对于这种情况,由于采用了 true 标志位,因此生成了一条新的”子路径“,所以在调用 close 方法之后,连接的是当前子路径的源点和当前点。
如果对于当前”子路径“来说,它的"当前点"和"源点"不重合,那么会绘制一条从当前点到源点的直线。

除了采用连线的方法来确定一条路径, Path 还提供了 addXXX 来直接地增加一整段的路径,下面是相关的方法:
下面是运行的结果:

关于填充类型的方法有如下这些:
关于这个 FillType 的理解,下面这篇文章的作者说的很好:

我这里只是稍微地总结一下:

我们都知道 Paint 有三种模式: FILL/FILL_AND_STROKE/STROKE ,对于 STROKE 来说,是只绘制轮廓,而两种模式都涉及到”填充“,那么”填充“就涉及到怎么定义一个 Path 所组成的图形的内部, FillType 就是用来确定这个所谓的”内部“的定义的,需要注意,只讨论封闭图形的情况。
关于 Path 的计算,有下面这两个方法:
我们以 XOR 为例子:

最后的结果为:

Path 提供了两种重置方法:


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12899258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-28
下一篇 2023-05-28

发表评论

登录后才能评论

评论列表(0条)

保存