Android SVG的pathData详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android SVG的pathData详解相关的知识,希望对你有一定的参考价值。

参考技术A 上上篇讲到SVG的动画.但是没详细讲到pathData里面的详细路径.

比如下面这个图形

看到这里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)

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

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

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

这里面没讲到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) 终点的位置

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

转动x轴~~~

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

现在取小弧度看看

再修改为逆时针,

椭圆的属性 差不多讲解完成了,如下
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轴。
这是前辈留下的图:

Android利用SVG实现动画效果

系列文章目录

Android利用SVG实现动画效果


老规矩,文中/文末会放置源码


前言

在之前一篇文章中利用drawLine实现了线条动画的效果,然后在大佬的介绍下查看了TrimPathStart/End,感觉有必要写一篇文章。


以下是本篇文章正文内容

一、先看看Android中一个简单的SVG图

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="200dp"
    android:viewportWidth="200"
    android:viewportHeight="200">

  <path
      android:name="start"
      android:pathData="M100 4 l-100 192 l192 0 z"
      android:strokeWidth="3"
      android:strokeColor="#a2d7dc"/>

</vector>

看看大致的动画效果(动画执行效果,顺序与绘制相反)

二、pathdata中参数的定义(三角形是怎么绘制出来的)

参数定义:大写的命令为绝对坐标命令;小写的命令为相对坐标命令

  • M=moveto 命令 M or m ,移动到新的位置
  • Z=closepath 命令 Z or z,封闭路径
  • L=lineto 命令 L or l,从当前的位置画一条线到指定位置
  • H=horizontal lineto 命令 H or h,水平画一条直线到指定位置
  • V=vertical lineto 命令 V or v,垂直画一条直线到指定位置
  • Q=quadratic Bézier curve 命令 Q or q ,贝塞尔曲线(Android学习自定义view必备基础)
  • T=smooth quadratic Bézier curveto 命令 T  光滑二次贝塞尔曲线
  • A=elliptical arc  命令 A 椭圆弧seg

1.Demo绘制三角形的解读:

代码如下:

 android:pathData="M100 4 l-100 192 l192 0 z"
 //为了方便讲解改成如下
  android:pathData="M100 4 l-100 192 l192 0 l-92,-194"

M100 4:起点为100,4(x为100,y为4)。
l-100 192: l命令是从当前的位置画一条线到指定位置,-100是减少 ,从最开始的值开始计算100-100,4+192,第二个点为0,196(x为0,y为196)。
l192 0 :同上,从上一个点计算0+192,196+0,第三个点为 192,196(x为192,y为196)。
l-92,-194:回到原点。

实际绘制效果:

三、动画效果的实现

1.在bulid.gradle(Module:app)中增加对vectorDrawables的支持。

    defaultConfig {
        ...........
        //增加对vectorDrawables的支持
        vectorDrawables.useSupportLibrary = true

    }

2.以上步骤画出的SVG图:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="200"
android:viewportHeight="200">

<path
    android:name="start"
    android:pathData="M100 4 l-100 192 l192 0 l-92,-194"
    android:strokeWidth="3"
    android:strokeColor="#a2d7dc"/>

</vector>

3.在res文件夹下新建animator文件夹放置动画文件

动画文件代码(这个比较简单就不一一介绍了)。

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:propertyName="trimPathStart"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType">
</objectAnimator>

4.在drawable文件夹下新建文件将svg与动画进行关联

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:drawable="@drawable/你的svg名称">
    <target
        android:animation="@animator/你的动画名称"
        android:name="start"></target>
</animated-vector>

5.在ImageView中引用第4步的文件

    <ImageView
        android:id="@+id/iv"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        app:srcCompat="@drawable/taiji_anim" />

记得在根布局里加上:xmlns:app="http://schemas.android.com/apk/res-auto"

6.在Activity中启动动画

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private ImageView anim_path;

    private Drawable drawable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        anim_path = (ImageView) findViewById(R.id.iv);
        anim_path.setOnClickListener(this);

}

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv:
                startAnim(anim_path);
                break;
        }
    }

    /**
     * 启动动画
     *
     * @param iv
     */
    private void startAnim(ImageView iv) {
        drawable = iv.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }
}

7.实现效果

四、拓展工具

svg下载:阿里图库
svg转换为VectorDrawable工具:http://inloop.github.io/svg2android/

以上是关于Android SVG的pathData详解的主要内容,如果未能解决你的问题,请参考以下文章

Android利用SVG实现动画效果

滚动时如何填充svg

华为PAT端口地址映射配置详解

svg入门详解

华为PAT端口地址映射配置详解

PAT A1063——set的常见用法详解