美文网首页andriod
Android SVG的pathData详解

Android SVG的pathData详解

作者: ReleaseYH | 来源:发表于2018-01-10 12:20 被阅读0次

    上上篇讲到SVG的动画.但是没详细讲到pathData里面的详细路径.

    比如下面这个图形

      <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24dp"
         android:height="24dp"
         android:viewportHeight="24.0"
         android:viewportWidth="24.0">
       <path
            android:fillColor="#FF000000"
            android:pathData="M22,16
                     V4
                     c0,-1.1 -0.9,-2 -2,-2
                     H8
                     c-1.1,0 -2,0.9 -2,2
                     v12
                     c0,1.1 0.9,2 2,2
                     h12
                     c1.1,0 2,-0.9 2,-2z
                     m-11,-4
                     l2.03,2.71
                     L16,11
                     l4,5
                     H8
                     l3,-4z
                     M2,6
                     v14
                     c0,1.1 0.9,2 2,2
                     h14
                     v-2
                     H4
                     V6
                     H2z" />
    
    示例.png

    看到这里pathData里的数据,显而易见,我把图的每个画图步骤换行分解了。
    pathData 的指令基本都是由字母跟若干数字组成,数字之间可以用空格或者逗号隔开 (其实逗号会被忽略掉,加上逗号只是一些习惯的问题,方便查看)。一般来说指令字母分为大小写两种,大写的字母是基于原点的坐标系(偏移量),即绝对位置;小写字母是基于当前点坐标系(偏移量),即相对位置。

    M:move to 移动绘制点,作用相当于把画笔落在哪一点。
    L:line to 直线,就是一条直线,注意,只是直线,直线是没有宽度的,所以你什么也看不到。
    Z:close 闭合,嗯,就是把图封闭起来。
    C:cubic bezier 三次贝塞尔曲线
    Q:quatratic bezier 二次贝塞尔曲线
    A:ellipse 圆弧

    对应坐标的含义
    M (x y) 把画笔移动到x,y,要准备在这个地方画图了。
    L (x y) 直线连到x,y,还有简化命令H(x) 水平连接、V(y)垂直连接。
    Z,没有参数,连接起点和终点
    C(x1 y1 x2 y2 x y),控制点(x1,y1)( x2,y2),终点x,y 。
    Q(x1 y1 x y),控制点(x1,y1),终点x,y
    A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)

    移动
    M x,y ; (m dx, dy) 移动虚拟画笔到对应的点,但是并不绘制。一开始的时候默认是在(0,0)。

    比如现在,M22,16,就是将开始点定位到(22,16)这里。

    直线
    L x,y (l dx, dy) 从当前点划一条直线到对应的点。
    H x (h dx) 从当前点绘制水平线,相当于l x,0
    V y (v dy) 从当前点绘制垂直线,相当于l 0,y

    现在,V4 就是基于刚才(22,16)的基础上,在Y轴的方向画垂直线,X轴不变。划线到(22,4)这个点上。

    这里 c0,-1.1 -0.9,-2 -2,-2,c是三次贝塞尔曲线。小写说明是基于(22,4)点的相对坐标来进行绘制。
    0,-1.1是控制点1,-0.9,-2是控制点2,-2,-2是终点位置。所以基于相对位置。可以计算出控制点1的绝对位置。
    即是(22,2.9),控制点2是(21.1, 2),终点是(20,2)

    图1.png

    终点和起点连接起来也就成为这个图。
    同理剩下的也就可以形成正方形圆角

          <vector xmlns:android="http://schemas.android.com/apk/res/android"
              android:width="24dp"
              android:height="24dp"
              android:viewportWidth="24.0"
              android:viewportHeight="24.0">
           <path
              android:fillColor="#FF000000"
              android:pathData="M22,16
                           V4
                           c0,-1.1 -0.9,-2 -2,-2
                           H8
                           c-1.1,0 -2,0.9 -2,2
                           v12
                           c0,1.1 0.9,2 2,2
                           h12
                           c1.1,0 2,-0.9 2,-2z
                           "/>
        </vector>
    
    图片2.png 然后是如何实现中间镂空的图形呢。 图3.png

    由于我们画正方形的时候是逆时针来画,如果这个山形也是逆时针来画的话,也就重叠看不见了。所以要顺时针来画山形。在此基础上加上m-11,-4 l2.03,2.71 L16,11 l4,5 H8 l3,-4z 也就可以看见了。

      <vector xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="24dp"
            android:height="24dp"
            android:viewportWidth="24.0"
            android:viewportHeight="24.0">
        <path
            android:fillColor="#FF000000"
            android:pathData="M22,16
                         V4
                         c0,-1.1 -0.9,-2 -2,-2
                         H8
                         c-1.1,0 -2,0.9 -2,2
                         v12
                         c0,1.1 0.9,2 2,2
                         h12
                         c1.1,0 2,-0.9 2,-2z
                         m-11,-4
                         l2.03,2.71
                         L16,11
                         l4,5
                         H8
                         l3,-4z
                         "/>
      </vector>
    

    剩下的那个图形也就非常简单了。

    这里面没讲到A命令的具体的使用。
    A rx,ry x-axis-rotation large-arc-flag,sweepflag x,y
    a rx,ry x-axis-rotation large-arc-flag,sweepflag dx,dy
    rx ry 椭圆半径
    x-axis-rotation x轴旋转角度
    large-arc-flag 为0时表示取小弧度,1时取大弧度(要长的还是短的)
    sweep-flag 0取逆时针方向,1取顺时针方向
    x,y (dx,dy) 终点的位置

      android:pathData=" M50,50 a10,5 0,1 0 1,0" />
    

    以50,50为起点,逆时针画
    椭圆图形,x轴半径10,y轴半径5

    image

    转动x轴~~~

      android:pathData=" M50,50 a10,5 90,1 0 1,0" />
      我想要椭圆上半段,此处修改为x轴半径的两倍
      android:pathData=" M50,50 a10,5 90,1 0 20,0" />
      椭圆左半段
      android:pathData=" M50,50 a10,5 90 1 0 0 10" />
      椭圆右半段
      android:pathData=" M50,50 a10,5 90 1 1 0 10" />
    
     <path
          android:fillColor="#fff70000"  下
          android:pathData=" M50,50 a10,5 0 1 0 1 0" />
      <path
          android:fillColor="#FFF22420" 上
          android:pathData=" M50,50 a10,5 0 1 1 1 0" />
      <path
          android:fillColor="#fff57000"右
          android:pathData=" M50,50 a10,5 0 1 1 1 1" />
      <path
          android:fillColor="#FF323243"左
          android:pathData=" M50,50 a10,5 0 1 0 0 1" />
    
    image

    出现上面的情况可以想到是因为,起始点50,50在椭圆中的位置不同。那么,再修改一下。

      android:pathData=" M50,50 a10,5 0 1 1 0 7" />  修改了右边椭圆的代码
      现在取的是大弧度,所以看到这样的效果,如果 7改为10(也就是y轴半径的两倍)这刚好会在 一半的位置。
    

    现在取小弧度看看

      android:pathData=" M50,50 a10,5 0 0 1 0 7" /> ,可以看到小弧度 顺时针画图。
    
    image

    再修改为逆时针,

      android:pathData=" M50,50 a10,5 0 0 0 0 7" /> 
    

    椭圆的属性 差不多讲解完成了,如下
    android:pathData=" M50,50 a10,5 0 0 0 0 7" />
    10,5 为椭圆x,y轴半径
    第一个0 为 x轴旋转角度
    第二个0 为取大小弧度,0为小,1为大
    第三个0 为顺逆时针,0为逆1为顺
    第四个0 为修改起始点在椭圆中的位置,y轴.
    第五个 7 为修改起始点在椭圆中的位置,x轴。
    这是前辈留下的图:

    image

    相关文章

      网友评论

        本文标题:Android SVG的pathData详解

        本文链接:https://www.haomeiwen.com/subject/nqennxtx.html