SurfaceView的入门(三)-----surfaceView绘制动画切换图片效果

转载:https://blog.csdn.net/wangpeiming110/article/details/74638916

源码下载

前言:

     之前在SurfaceView(一)中提到了SurfaceView的基础实现,然后现在在那个基础之上,开始使用SurfaceView来进行的动画的实现。

SurfaceView的画图部分

 private volatile boolean isPause;
    private boolean isFirst;
    @Override
    public void run() {
        while (mIsDrawing) {
                if (isPause) {
                } else {
                    if (isFirst) {
                        animManager.updateStartTime();
                        isFirst=false;
                    }
                    animManager.draw();
                }
            }
    }

    public void setPause(boolean isPause) {
        if(isPause)isFirst=true;
        this.isPause = isPause;
    }

由于避免重复,之前的那些初始化步骤省略了,详细的可以下面:

surfaceView(入门一):https://blog.csdn.net/qq_35014796/article/details/80783357

具体的动画实现逻辑:

     百叶窗效果:
 private Path path = new Path();
    private float bailine = 5;//百叶窗的行数
    private int sum;
    private void AnimBaiYeChuang() {
        path.reset();
        for (int i = 0; i < bailine; i++) {
            float top = height / bailine * i;//height:屏幕的高度 bailine: 百叶窗的行数
            float bottom = top + height / bailine * rate;//rate 比率 0-1之间的值 float类型
            path.addRect(0, top, width, bottom, Path.Direction.CW);//路径添加画的矩形
        }
        mCanvas.clipPath(path);//按路径进行裁剪
        index=index%bitmaps.size();//图片的索引
        Log.i(TAG, "AnimBaiYeChuang: "+sum++);//调用了45次
        mCanvas.drawBitmap(bitmaps.get(index), null, rect, paint);//画布进行图片的画质
        initAnim(1);
    }
      阶梯动画效果:
 private int timeInterval = 200;//每一行阶梯与上一行起跑时间差
    private int lineNum=4;//有多少个阶梯
    private float timePerLine = animtime - (timeInterval * (lineNum - 1));//为了保证最后一个阶梯能够占满宽度,我们要得出第一个占满宽度的时间
    public void AnimJieTi(){
        path.reset();
        /*
        * 原本是 width-(rate*animtime)/animtime*width;这样子得出的是动画时间内left坐标的位置
        * 但是这个样子并没有阶梯分层的效果,要有效果就要引入当前阶梯行数(i)和timeIntervald的关系
        * 所以更改为 (rate * animtime - i * timeInterval)/animtime
        * 然后上面因为添加i*timeInterva所以在原来的基础上也要改的
        * 上面说了timePerLine,为第一个阶梯占满宽度的时间,所以更改为
        * (rate * animtime - i * timeInterval) / timePerLine
        *
        * */
        float left1 = width - (rate * animtime - 0 * timeInterval) / timePerLine * width;//
        float top1 = height / lineNum * 0;
        float right1 = width;
        float bottom1 = top1 + height / lineNum;
        path.addRect(left1, top1, right1, bottom1, Path.Direction.CW);

        //计算每一行需要展示的左上右下
        for (int i = 1; i < lineNum; i++) {
            float left = width - (rate * animtime - i * timeInterval) / timePerLine * width;
            Log.i(TAG, "AnimJieTi: left:  "+left);

            float top = height / lineNum * i;
            float right = width;
            float bottom = top + height / lineNum;

            path.addRect(left, top, right, bottom, Path.Direction.CW);
        }
        mCanvas.clipPath(path);
        index=index%bitmaps.size();
        mCanvas.drawBitmap(bitmaps.get(index), null, rect, paint);
        initAnim(2);
    }
     棋盘效果:
int rowNum = 9;//一行有多少个格子
    int colNum = 6;//一列有多少个格子
    public void AnimQiPan() {
        path.reset();
        //根据行数和列数计算每一个格子区域,最后剪切出棋盘区域
        for (int i = 0; i < rowNum; i++) {
            //单数行没有问题,双数行要从第一行-1行和第一行的第一个格子和第三个格子之间开始,除以2是为了配合第二行的第一个格子只占用原来的一半
            float leftStart = i % 2 == 0 ? 0 : -(width / colNum) / 2;
            for (int j = 0; j < colNum+1 ; j++) {//这里加1因为双数行有比原来多一个
                float left = leftStart + j * width / colNum;
                float top = height / rowNum * i;
                float right = left + width / colNum * rate;
                float bottom = top + height / rowNum;
                path.addRect(left, top, right, bottom, Path.Direction.CW);
            }
        }
        mCanvas.clipPath(path);
        index=index%bitmaps.size();
        mCanvas.drawBitmap(bitmaps.get(index), null, rect, paint);
        initAnim(3);
    }
     随机线条效果:
 int restNum;//剩余数量的,用于随机线条一开始是高度-1
    Random random = new Random();//用于随机线条和溶解
    int[] lines;//这个是高的值
    public void AnimSuiJiXian() {
        path.reset();
        //计算这一次需要取得的线条数量
        int needNum = (int) ((height - 1) * rate - (height - 1 - restNum));
        //循环随机获取线条数组中的线条
        //新加的
        for (int i = 0; i < needNum; i++) {
            //获取到一条随机线条,添加进path中
            int r = random.nextInt(restNum - i);
            path.addRect(0, lines[r], width, lines[r] + 1, Path.Direction.CW);


            //保证之后再r中渠道的线段不是已经用过的
            int temp = lines[r];
            lines[r] = lines[restNum - i - 1];
            lines[restNum - 1 - i] = temp;
        }
        //以前的
        //遍历数组中“之前已取”的线条,全部放在path中
        for (int i = 0; i < (height - 1) - restNum; i++) {
            path.addRect(0, lines[(int) (height - 2 - i)], width, lines[(int) (height - 2 - i)] + 1, Path.Direction.CW);
        }
        //剩余线条数量
        restNum = restNum - needNum;
        mCanvas.clipPath(path);
        index=index%bitmaps.size();
        mCanvas.drawBitmap(bitmaps.get(index), null, rect, paint);
        initAnim(0);
    }
效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值