美文网首页
Android 绘制水波纹小球球

Android 绘制水波纹小球球

作者: 带带我 | 来源:发表于2021-03-12 11:55 被阅读0次
1615521127828.gif
public class BezierCurvePercentView extends View {

    //外圈
    private Paint paintOutside;
    private int paintOutsideColor = Color.parseColor("#FD6F5C");
    //背景色
    private Paint paintBg;
    private int paintBgColor = Color.parseColor("#F4F4F4");
    //已使用百分比
    private Paint paintPercent;
    private int paintPercentColor = Color.parseColor("#FD6F5C");
    private Path percentPath;
    //文本
    private Paint paintText;
    private int paintTextColor = Color.parseColor("#ffffff");
    private float percent = 0.3f;

    /**
     * 波纹的长度
     */
    private int WAVE_LENGTH = 300;

    /**
     * 波纹的高度
     */
    private final static int WAVE_HEGHT = 20;
    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);

    private int viewWidth;
    private int viewHeight;
    private int dx;

    public BezierCurvePercentView(Context context) {
        super(context);
    }

    public BezierCurvePercentView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paintOutside = new Paint();
        paintOutside.setAntiAlias(true);
        paintOutside.setColor(paintOutsideColor);
        paintOutside.setStrokeWidth(3f);
        paintOutside.setStyle(Paint.Style.STROKE);

        paintBg = new Paint();
        paintBg.setAntiAlias(true);
        paintBg.setColor(paintBgColor);
        paintBg.setStyle(Paint.Style.FILL);

        paintPercent = new Paint();
        paintPercent.setAntiAlias(true);
        paintPercent.setColor(paintPercentColor);
        paintPercent.setStyle(Paint.Style.FILL);
        percentPath = new Path();

        paintText = new Paint();
        paintText.setAntiAlias(true);
        paintText.setColor(paintTextColor);
        paintText.setStrokeWidth(2f);
        paintText.setTextSize(100);
        paintText.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        viewHeight = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int layerId = canvas.saveLayer(0, 0, viewWidth, viewHeight, null, Canvas.ALL_SAVE_FLAG);

        canvas.drawCircle(viewWidth/2, viewHeight/2, viewWidth/2-2, paintOutside);
        canvas.drawCircle(viewWidth/2, viewHeight/2, viewWidth/2-3, paintBg);

        percentPath.reset();
        percentPath.moveTo( -WAVE_LENGTH + dx, (1-percent)*viewHeight);
        for (int i = -WAVE_LENGTH; i < getWidth() + WAVE_LENGTH; i += WAVE_LENGTH) {
            percentPath.rQuadTo(WAVE_LENGTH / 4, -WAVE_HEGHT, WAVE_LENGTH / 2, 0);
            percentPath.rQuadTo(WAVE_LENGTH / 4, WAVE_HEGHT, WAVE_LENGTH / 2, 0);
        }
        percentPath.lineTo(viewWidth, viewHeight);
        percentPath.lineTo(0, viewHeight);
        percentPath.close();

        paintPercent.setXfermode(mMode);
        canvas.drawPath(percentPath, paintPercent);

        paintPercent.setXfermode(null);

        Rect rect = new Rect();
        String textStr = (int)(percent*100) + "%";
        paintText.getTextBounds(textStr, 0, textStr.length(), rect);
        canvas.drawText(textStr, viewWidth/2 - rect.width()/2, viewHeight/2 + rect.height()/2, paintText);
        canvas.restoreToCount(layerId);
    }

    public void setPercent(float percent){
        this.percent = percent;
        ValueAnimator mValueAnimator = ValueAnimator.ofInt(0, WAVE_LENGTH);
        mValueAnimator.setDuration(2000);
        mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        // 动画插值器,也可以使用其他
        mValueAnimator.setInterpolator(new LinearInterpolator());
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                dx = ( int ) animation.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator.start();
    }
}

二阶贝塞尔曲线的两个方法 quadTo 与 rQuadTo

path.moveTo(x, y);
quadTo(x1, y1, x2, y2);
quadTo(x3, y3, x4, y4);
此方法中的每个坐标是相对起点的坐标,即 x1-x = x2-x1 = x3-x2 = x4-x3;
path.moveTo(x, y);
rQuadTo(x1, y1, x2, y2);
rQuadTo(x3, y3, x4, y4);

此方法中的每个坐标是相对上一个点的坐标,假设起点是(0, 0),波长是100,波高度20,则:

path.moveTo(0, 0);
rQuadTo(100/4, 20,100/2, 0);
↓↓↓第二段曲线 (x,y)把上一个点看做(0, 0)即相对上一个点X位移量为1/4波长=100/4,Y减少波高度20
rQuadTo(100/4, -20, 100/2, 0);

完整曲线共5个点,如下图:
path.moveTo(起点x, 起点y);
quadTo(Ax, Ay, Bx, By);
quadTo(Cx, Cy, Dx, Dy);


二阶贝塞尔.jpg

相关文章

  • Android 绘制水波纹小球球

    二阶贝塞尔曲线的两个方法 quadTo 与 rQuadTo 完整曲线共5个点,如下图:path.moveTo(起点...

  • Android 路径绘制艺术——贝塞尔曲线

    目录 1)什么是贝塞尔曲线 2)贝塞尔曲线图解 3)Android绘制贝塞尔曲线 4)绘制水波纹效果 概述 什么是...

  • Flutter贝塞尔曲线之水波纹与球形进度(二)

    续上篇,再用贝塞尔曲线绘制一个循环水波纹,一个水波纹进度球,先看效果,以下效果的实现用的都是二阶贝塞尔曲线。 效果...

  • 小球球

    上个月19号,邱先生下班路上捡了两只小奶狗。只有拳头那么大,车子开过的时候我以为就是普通的垃圾的,邱先生眼尖...

  • 小球球

    看到暖妈这篇文章,我得心也定了下来,因为我从来没养过小动物,9月份带老公孩子去花卉市场时,孩子看到一只刚出生的小博...

  • 小球球

    你们应该都知道球球是谁吧。对的,它是我的狗。 今天我们去老家喂狗的时候看见球球那可怜的样子,感到心痛,为什么可怜呢...

  • 2019-11-05

    水波纹,interpolator加速器属性值 ------- 水波纹效果实现: 点击水波纹效果:只有android...

  • canvas练习之躁动的小球

    1.绘制若干个小球 2.让每个小球都是些碰壁反弹 3.当两个小球之间的距离到达指定长度时,在这两个小球中间绘制一条...

  • android 自定义view-水波纹进度球

    android 进阶之路-自定义view-水波纹进度球 如果你是老司机,一看标题就会就return吧,嘻嘻。 在我...

  • RecyclerView

    默认水波纹实现方式android:background="?android:attr/selectableItem...

网友评论

      本文标题:Android 绘制水波纹小球球

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