Android使用SVG矢量图打造酷炫动画效果(2)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
              "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg xmlns="http://www.w3.org/2000/svg"
   
    viewBox="0 0 668 175">
  <path
        fill="none" stroke="black" stroke-width="1"
        d="M 530.00,34.00
          C 530.00,34.00 526.08,59.00 526.08,59.00
            526.08,59.00 518.00,105.00 518.00,105.00
            518.00,105.00 515.42,119.00 515.42,119.00
            515.42,119.00 513.26,125.01 513.26,125.01
            513.26,125.01 506.00,126.00 506.00,126.00
            506.00,126.00 496.00,126.00 496.00,126.00
            496.00,126.00 496.00,120.00 496.00,120.00
            490.87,124.16 486.71,126.42 480.00,126.91
            475.71,127.22 471.06,126.94 467.00,125.44
            454.13,120.68 451.86,110.19 452.00,98.00
            452.22,79.34 465.14,64.55 484.00,63.18
            492.14,62.59 498.96,65.71 504.00,72.00
            504.00,72.00 510.00,34.00 510.00,34.00
            510.00,34.00 530.00,34.00 530.00,34.00 Z
          M 551.00,56.89
          C 539.01,55.86 537.45,39.82 551.00,35.55
            568.60,33.45 567.67,58.33 551.00,56.89 Z

中间段省略

M 263.00,134.00
          C 263.00,134.00 263.00,145.00 263.00,145.00
            263.00,145.00 202.00,145.00 202.00,145.00
            202.00,145.00 202.00,134.00 202.00,134.00
            202.00,134.00 263.00,134.00 263.00,134.00 Z" />
</svg>

根据图形路径的复杂度,生成的path数据复杂度也不一样,但格式也算是非常的清楚,即采用一定的指令把数据点进行拼接;
现在有了这些数据点,我们需要做的则是对数据进行解析,封装成我们要的Path;

解析的过程也无非是 遇到指令则采用android Path 里的对应方法进行置换,解析方式如下:

public Path parsePath(String s) throws ParseException {
        mCurrentPoint.set(Float.NaN, Float.NaN);
        mPathString = s;
        mIndex = 0;
        mLength = mPathString.length();

PointF tempPoint1 = new PointF();
        PointF tempPoint2 = new PointF();
        PointF tempPoint3 = new PointF();

Path p = new Path();
        p.setFillType(Path.FillType.WINDING);

boolean firstMove = true;
        while (mIndex < mLength) {
            char command = consumeCommand();
            boolean relative = (mCurrentToken == TOKEN_RELATIVE_COMMAND);
            switch (command) {
                case 'M':
                case 'm': {
                    // m指令,相当于android 里的 moveTo()
                    boolean firstPoint = true;
                    while (advanceToNextToken() == TOKEN_VALUE) {
                        consumeAndTransformPoint(tempPoint1,
                                relative && mCurrentPoint.x != Float.NaN);
                        if (firstPoint) {
                            p.moveTo(tempPoint1.x, tempPoint1.y);
                            firstPoint = false;
                            if (firstMove) {
                                mCurrentPoint.set(tempPoint1);
                                firstMove = false;
                            }
                        } else {
                            p.lineTo(tempPoint1.x, tempPoint1.y);
                        }
                    }
                    mCurrentPoint.set(tempPoint1);
                    break;
                }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f7ede327a2e516cf05b16f3f25920884.html