Operating on canvas canvas to see this one is enough!

canvas

canvas is a particularly important part of Android custom drawing, if you want to want to draw graphics, canvas operation can help you a whole lot easier.

canvas.save()和canvas.restore() 

These two methods are the first to be understood, save the current method is to save the canvas state, restore method is to return the state to the state on a canvas of the canvas, so when we need to draw some small canvas graphics operation time , to save and then restore, and then a write operation in the middle of the canvas two methods.

Ready to work:

New java file MyView, custom brush, do some simple initialization
private Paint mPaint;


    public MyView(Context context) {
        super(context);
        initSomeThing();
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initSomeThing();
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initSomeThing();
    }

private void initSomeThing() {
        mPaint = new Paint();
        initPaint(mPaint);
    }

    private void initPaint(Paint paint) {
        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.rgb(0x00, 0x00, 0x00));
    }

Translation

First draw a circle, and then follow the steps in the same pan canvas painting of a circle
 
   
canvas.drawCircle(100, 100, 100, mPaint);
canvas.save();
canvas.translate((float) 141.42135623731, (float) 141.42135623731);
mPaint.setColor(Color.rgb(0x91, 0xbe, 0xf0));
canvas.drawCircle(100, 100, 100, mPaint);
mPaint.setColor(Color.BLACK);
canvas.restore();
 
   
运行一下,效果如下:


同样是画两个一样的圆,结果却出现这种情况,原因是画布进行操作的时候,对应的坐标轴也跟着改变,其实我更加喜欢理解的是,我们操作的坐标轴。
canvas.translate这个方法里面的两个参数分别是向XY平移的距离,这个很简单就不赘述了

缩放

先做准备工作,把画布平移到平移到屏幕中间,画一个坐标轴,然后画一个方便比较的矩形
mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);

        canvas.save();

        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.drawLine(-550, 0, 550, 0, mPaint);
        canvas.drawLine(0, -800, 0, 800, mPaint);


        canvas.restore();
        mPaint.setStrokeWidth(0);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.FILL);

//X中心轴是Y轴   Y中心轴是X轴

//        [-∞, -1)	        先根据缩放中心放大n倍,再根据中心轴进行翻转
//        -1	            根据缩放中心轴进行翻转
//        (-1, 0)	        先根据缩放中心缩小到n,再根据中心轴进行翻转
//        0	                不会显示,若sx为0,则宽度为0,不会显示,sy同理
//        (0, 1)	        根据缩放中心缩小到n
//        1	                没有变化
//        (1, +∞)	        根据缩放中心放大n倍


        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);


        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF, mPaint);
        //缩放
        canvas.scale(0.5f, 0.5f);

        mPaint.setColor(Color.BLUE);
        canvas.drawRect(rectF, mPaint);
        mPaint.setColor(Color.BLACK);

        canvas.restore();

        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);

运行效果如下:

 
You can see the blue rectangle is narrow rectangular XY both directions after half of
This method of scaling parameters which follows
        [-∞, -1) according to the zoom center amplified n times, and then reversed on the central axis of
         -1 reversed on the zoom center axis
        (-1, 0) is first reduced to n according to the zoom center, and then reversed on the central axis
         0 does not appear, if sx is 0, the width of 0, not displayed, sy Similarly
         (0, 1) n according to the scaling down to the center
         1 does not change
         (1, + ∞) enlarged n times according to the zoom center
Above, there are written

There was a four parameter scaling method, the latter two points are the coordinates of the center of rotation, personal feeling, which can not actually remember the operation in two steps, first rotation center shifted to the canvas, and then use the above method rotation effect is the same, better understanding. But I wrote this
 mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.GREEN);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);

        canvas.scale(0.5f, 0.5f, 150, 0);
        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF, mPaint);

        canvas.restore();

        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);

Operating results are as follows:


The new green rectangle is drawn rectangle

Rotation

 mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(15);
        mPaint.setColor(Color.GRAY);

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.rotate(45);
        //区域是距离页面左上右下    所以不是之前说的对边两个点,X2要>X1 ,Y2要>Y1   0,0,400,-400   不符合就画不出矩形
        RectF rectF = new RectF(0, -300, 300, 0);
        canvas.drawRect(rectF , mPaint);

        canvas.restore();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(0);
        mPaint.setColor(Color.BLACK);

需要注意的是,旋转里面填的那个参数是旋转角度,不是旋转的弧度,是360度那个角度不是2π那个角度,
还有就是正方向是顺时针,填负数就是逆时针旋转。

运行效果如下:


还有一个三参的方法,和缩放一样,个人建议还是先平移再旋转吧,懒得写了

对了,缩放还有一个比较有意思的玩法,先新建一个类,直接贴代码

public class ViewScaleFun extends View {

    private Paint mPaint;

    public ViewScaleFun(Context context) {
        super(context);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
    }

    public ViewScaleFun(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public ViewScaleFun(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();

        canvas.translate(getWidth() / 2, getHeight() / 2);

        RectF rectF = new RectF(-500, -500, 500, 500);

        for (int i = 0; i < 30; i++) {
            canvas.scale(0.9f, 0.9f);
            canvas.drawRect(rectF, mPaint);
        }


        canvas.restore();

    }
}

运行结果如下:



哈哈  炫不酷炫酷   想不想学  







发布了124 篇原创文章 · 获赞 141 · 访问量 16万+

Guess you like

Origin blog.csdn.net/weixin_36838630/article/details/76146700