天天看点

svg初探,绘制爱心

svg初探,绘制爱心

1、svg图片

   svg和bitmap的区别  不详细介绍了

   首先强烈推荐阿里 iconfont 简单粗暴

   找一张图片下载 可以调整图片属性  选择svg下载

svg初探,绘制爱心

   然后打开android studio module 右键drawable

svg初探,绘制爱心
svg初探,绘制爱心

   选中下载的svg图片  这里可以调整图片属性  然后生成对应的.xml文件

   最后的使用是一样的  android:src="@drawable/ic_xxxxx" 等等

2、svg属性
 打开导入svg生成的xml文件  发现是这个样子
 
 一脸懵逼,什么鬼。
 淡定 属性讲解
 <vector xmlns:android="http://schemas.android.com/apk/res/android"  //命名空间
    android:height="200dp"  //这个是图片的intrinsic高度
    android:width="200dp"   //这个是图片的intrinsic宽度
    android:viewportHeight="100"    //这个是为这个图片设置的纵坐标,表示将图片分为100等份,主要下面的pathData需要依赖这个坐标的划分
    android:viewportWidth="100"     //同上,只不过这个是横坐标,这两个值可以随便定
    android:alpha="0.2"     //这个是整个图像的透明度,取值范围0到1
    >

    <group      //这个标签中可以放入若干个<path/>标签,并给它们设置一些共同的属性
        android:name="group_name"   //这个name很有用,在设置objectAnimator的时候用来区分给那个部分施加动画
        android:pivotY="50"     //这个设置这个group的中心点的X坐标,取值范围为0到100,在做rotation时有用
        android:pivotX="50"     //这个设置这个group的中心点的Y坐标,取值范围为0到100,在做rotation时有用
        android:translateX="20" //将整个group在X轴方向平移多少像素
        android:translateY="30" //将整个group在Y轴方向平移多少像素
        android:rotation="90"   //将整个group以中心点左边旋转的角度,360为一圈
        android:scaleX="0.5"    //横坐标的缩放比例 , 取值1表示100%
        android:scaleY="0.3">   //纵坐标的缩放比例,取值0.5表示50%,取值1.5表示150%

        <path   //这个标签是重头戏,矢量图绘制的路径
            android:name="path_name"    //为这个path标记的名字,在使用objectAnimator的时候用来区分给哪个部分施加动画

            android:pathData="m 0,0 L50,0 L100,100 L0,100 z"    //这个具体语法,在网上随便搜搜就有了,就是SVG的语法,如果这个都不明白,那么你肯定不明白什么是矢量图,找点资料再看看吧,这篇文章不适合你

            android:fillColor="@color/red"  //图形内部的夜色
            android:fillAlpha="1"       //图形的透明度取值范围0到1
            android:strokeAlpha="0.5"   //线条的透明度,取值范围0到1
            android:strokeColor="#ff0000ff" //线条的颜色
            android:strokeLineCap="butt|round|square"   //线的末端形状,butt严格到指定的坐标就截至,round圆角的先端边缘,square方形的边缘不过有点向外延伸
            android:strokeLineJoin="round|bevel|miter"  //线的连接处形状,round是圆角的,bevel和miter貌似看不出来有什么区别....
            android:strokeWidth="20"    //线段的宽度

            android:trimPathStart="0.5"    //顾名思义,从path开始的地方(0%)去除path,去除到指定的百分比位置,取值范围0到1
            android:trimPathEnd="0.5"      //顾名思义,从path结束的地方(100%的地方)去除path,去除到指定的百分比位置,取值范围0到1
            android:trimPathOffset="0.5"   //这个属性是和上面两个属性共同使用的,单独使用没有用,这个属性的意思是,在去除path的时候设置path原点的位置,按百分比设置,取值范围0到1
            />
    </group>

</vector>
           
3、svg动画
动画 特效 。。。 头皮发麻有没有
svg可以打造非常炫酷的动画   这里先来绘制简单的线条动画

图片看起来很卡顿  但是实际运行效果是非常流畅的!
绘制动画前 先来了解点东西
           
Android对于 SVG 的支持是从 Android L 开始的,它的 SDK 里面加入了 VectorDrawable , AnimatedVectorDrawable 等类帮助我们构建 SVG 图形以及动画,并且你可以在 xml 文件里面直接使用 <vector/> 标签绘制 SVG 图像以及 <animated-vector/> 标签为 SVG 图像分配动画

使用path标签创建SVG,就像用指令的方式来控制一只画笔,例如移动画笔到某一坐标位置,画一条线,画一条曲线,结束。path标签所支持的指令有以下几种。
           
M = moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制

L = lineto(L X,Y):画直线到指定的坐标位置

H = horizontal lineto(H X):画水平线到指定的X轴坐标

V = vertical lineto(V Y):画垂直线到指定的Y轴坐标

C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝塞曲线

S = smooth curveto(S X2,Y2,ENDX,ENDY):三次贝塞曲线

Q = quadratic Belzier curveto(Q X,Y,ENDX,ENDY):二次贝塞曲线

T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路径后的终点

A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线

Z = closepath():关闭路径
           
OK 简单了解了点属性  那看代码  根据代码来推敲 效果会好很多
           
4根线条代码  在drawable中新建 text.xml
           
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportHeight="100"
android:viewportWidth="100">

<path
android:name="heart1"
android:pathData="
M13,20  C 9,40, 5,60, 2,80 L14,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart2"
android:pathData="
M30,38 C20,30,10,40,11.5,50  C11.5,58.5,20,65,30,70  C40,65,48.5,58.5,48.5,50  C50,40,40,30,30,38Z"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart3"
android:pathData="
M30,50 L30,55L30,50L35,50L30,50L60,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

<path
android:name="heart4"
android:pathData="
M75,55 L75,65 C75,70,80,75,85,75C90,75,95,70,95,65L95,55"
android:strokeColor="#E91E63"
android:strokeWidth="1" />

</vector>

定义的宽高是256dp 然后viewportHeight viewportWidth都是100  即宽高的每个单位是2.56dp
可以用白纸画出来  一个宽高256dp的正方形  100等分
每根线条的pathData 对应上面的属性来理解都很简单   现在讲讲爱心怎么绘制
           
参考
https://www.cnblogs.com/wjtaigwh/p/6652510.html
贝塞尔曲线函数难点是在坐标定位   网上应该有很多贝塞尔曲线定点工具

先用4根贝塞尔曲线绘制个圆
           
svg初探,绘制爱心
再根据爱心的变化  调整几个坐标点即可
参考 https://www.cnblogs.com/wjtaigwh/p/6652510.html
线条画完  再加入动画  
在drawable中新建 text_vector_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/text">
<target
android:name="heart1"
android:animation="@animator/heart_animator" />

<target
android:name="heart2"
android:animation="@animator/heart_animator" />

<target
android:name="heart3"
android:animation="@animator/heart_animator" />

<target
android:name="heart4"
android:animation="@animator/heart_animator" />
</animated-vector>
           
在drawable中新建 heart_animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="6000"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />

<!-- trimPathEnd 开始到结束  trimPathStart结束到开始-->
           
最后在activity中调用  用的是kotlin
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
(svg_animator_text!!.drawable as Animatable).start()

完成
但是有些交互需要监听动画  该怎么办呢
上面svg动画强转Animatable类  进去看看
           
public interface Animatable {
void start();

void stop();

boolean isRunning();
}

是个接口  并且没有监听的方法  再看看其他强转的类  发现有个Animatable2  并且有个AnimationCallback回调 里面有动画监听
试试   发现报错  程序都运行不起来了   怎么办
初探svg  还没去看源码怎么办呢
然后又发现个Animatable2Compat类  运行成功
           
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
val animatable2 = svg_animator_text?.drawable as Animatable2Compat
animatable2.registerAnimationCallback(object : Animatable2Compat.AnimationCallback(){
override fun onAnimationEnd(drawable: Drawable?) {
    super.onAnimationEnd(drawable)
    println("onAnimationEnd")
    }

    override fun onAnimationStart(drawable: Drawable?) {
    super.onAnimationStart(drawable)
    println("onAnimationStart")
    }
})
           
最最最后   一定要记得svg兼容性  这里就不多说了  网上很多