Detailed explanation of Canvas API (Part 1)
Introduction to this section:
We spent 13 sections explaining in detail most of the commonly used APIs of the Paint class in Android. Let’s start with this section. Some common APIs of Canvas (drawing board), we have listed them in
- 8.3.1 Detailed explanation of three drawing tool classes
- We can call them Some of the methods are divided into the following categories:
- drawXxx method family: Draw a picture in the current drawing area with a certain coordinate value, and the layers will be superimposed. That is, the layer painted later will cover the layer painted previously.
- clipXXX method family: Cut out (clip) a new drawing area in the current drawing area, this The drawing area is the current drawing area of the canvas object. For example: clipRect(new Rect()), Then the rectangular area is the current drawing area of canvas
- getXxx method family: Get some values related to Canvas, such as width, height, screen density, etc.
- save(), restore(), saveLayer(), restoreToCount(), etc. save and restore layers The methods
- translate(translation), scale(zoom), rotate(rotation), skew(tilt )
Of course there are other scattered methods, well, starting from this section I will pick some interesting APIs to learn~
And this section will give you What it brings is translate(translation), scale(zoom), rotate(rotation), skew(tilt) And detailed explanations of save(), restore()!
Official API document: Canvas
In addition, we must first clarify the direction of the X-axis and Y-axis in Canvas:
1.translate(translation)
Method : translate(float dx, float dy)
Analysis: Translation, move the coordinate origin of the canvas x to the left and right, and y up and down. The default position of the canvas is (0,0)
Parameter : dx is the movement distance in the horizontal direction, dy is the movement distance in the vertical direction
Usage example:
for(int i=0; i < 5; i++) { canvas.drawCircle(50, 50, 50, mPaint); canvas.translate(100, 100); }Running effect :
2.rotate(rotate)
Method:rotate(float degrees) / rotate(float degrees, float px, float py)
Analysis: Rotate degrees around the coordinate origin, the value is positive clockwise
Parameters: degrees is the rotation angle, px and py are the coordinates of the center point of the specified rotation (px, py)
Usage example:
Rect rect = new Rect(50,0,150,50); canvas.translate(200, 200); for(int i = 0; i < 36;i++){ canvas.rotate(10); canvas.drawRect(rect, mPaint); }
Running effect:
Code Analysis:
Here we first call translate(200,200) to move the coordinate origin of the canvas to (200,200), and then draw, so we The drawing result can be completely displayed on the canvas. If we set (10,200,200) for rotate, it will look like this Result:
Do you have any questions? This involves the concept of multiple layers of Canvas. I will talk about it later~
3.scale( Scale)
##Method: scale(float sx, float sy) / scale(float sx, float sy, float px , float py)
Analysis: Scale the canvas
Parameters: sx is the horizontal scaling ratio, sy is the vertical scaling I don’t know the ratio, px and py either. Decimal means to reduce , Integer means to enlarge
Usage example:
canvas.drawBitmap(bmp,0,0,mPaint); canvas.scale(0.8f, 0.8f); canvas.drawBitmap(bmp, 0, 0, mPaint); canvas.scale(0.8f, 0.8f); canvas.drawBitmap(bmp,0,0,mPaint);
Running effect:
4.skew(skew)
method :skew(float sx, float sy)
Analysis: Slant, can also be translated as bevel, twist
Parameter : sx is the corresponding angle of tilt in the x-axis direction, sy is the corresponding angle of tilt in the y-axis direction, both values are tan values! They are all tan values! They are all tan values! For example, if you want to tilt 60 degrees in the x-axis direction, then the decimal value corresponds to: tan 60 = square root 3 = 1.732!
Usage example:
canvas.drawBitmap(bmp,0,0,mPaint); canvas.translate(200, 200); canvas.skew(0.2f,-0.8f); canvas.drawBitmap(bmp,0,0,mPaint);
Running effect:
##5. The concept of Canvas layer and detailed explanation of save() and restore()
We generally like to call Canvas canvas, and children always think that Canvas is A simple piece of drawing paper, then I think I would like to ask how multi-layer animation is completed using canvas? In the example of translate above, why? drawCircle(50, 50, 50, mPaint); The reference coordinate is always (50,50), so why does this effect occur? Children who have doubts may have been confusing the concept of screen with the concept of Canvas. Let’s restore it below. The crime scene where translate was called:As shown in the figure, the origin of the canvas coordinates moves 100 on the x and y axes each time; then if we want to return to (0,0) What about drawing new graphics at different points? How to break, translate(-100,-100) slowly translates back? Not really Confused...
Okay, let’s not get involved. We can save the current canvas state before doing translation transformation. In fact, Canvas is We provide support for layers, and these layers are managed according to the "stack structure"
When we call the save() method , will save the current Canvas state and add it to the Canvas stack as a Layer. In addition, this Layer is not a specific class, it is just a conceptual thing!
And when we call the restore() method, the previous Canvas state will be restored, and at this time the Canvas layer stack The Layer on the top of the stack will pop up, and the subsequent Layer will come to the top of the stack. At this time, the Canvas will return to the Canvas state saved at the top of the stack!
Simply put: save() pushes a Layer into the stack, and restore() pops up a Layer on the top of the stack. This Layer represents the Canvas. state! That is to say, you can save() multiple times or restore() multiple times, but the number of restore calls cannot be greater than save Otherwise an error will be thrown! This is what most people say on the Internet, but in actual testing no such problem occurred, even if I restored The number of times is more than save, and there are no errors~ Visual inspection is that the system has been changed. I will show it to everyone after the next test~Come on, write an example to verify the function of save and restore!
Write an example:
Example code:
canvas.save(); //保存当前canvas的状态 canvas.translate(100, 100); canvas.drawCircle(50, 50, 50, mPaint); canvas.restore(); //恢复保存的Canvas的状态 canvas.drawCircle(50, 50, 50, mPaint);
Running result:
Needless to say, the code and results have explained everything, let’s make it more complicated and let’s do it Multiple save() and restore()!Example code:
canvas.save(); canvas.translate(300, 300); canvas.drawBitmap(bmp, 0, 0, mPaint); canvas.save(); canvas.rotate(45); canvas.drawBitmap(bmp, 0, 0, mPaint); canvas.save(); canvas.rotate(45); canvas.drawBitmap(bmp, 0, 0, mPaint); canvas.save(); canvas.translate(0, 200); canvas.drawBitmap(bmp, 0, 0, mPaint);
Run result:
Result Analysis:
First translate (300,300) to draw, then rotate 45 degrees to draw, then rotate 45 degrees to draw, then translate (0,200), During this period, save() is performed every time before drawing. You may have a question when you see this. The last translation is not a y movement of 200. Well, why did it turn to the left? Hehe, I will tell you that rotate() rotates the entire coordinate axis? coordinate axis Variety:Well, you understand rotate(), right? That’s ok, then let’s try restore~ We are in front of the final drawing Add two restore()!
canvas.restore(); canvas.restore(); canvas.translate(0, 200); canvas.drawBitmap(bmp, 0, 0, mPaint);
Run result:
Don’t say anything, experience it yourself, and add morerestore()!
It’s interesting, let’s continue adding restore()
##Well, it seems that we can’t write
restore anymore, right? Because we only saved four times. According to the Internet, This will report an error, is that really the case? Here we call the one provided by Canvas to get the current stack How many Layer methods are there: getSaveCount(); and then before and after save() and restore() Add a Log to print out the number of Layers in the stack:
The result is really gratifying. After all, practice brings true knowledge. It may be that Canvas has been modified, or for other reasons. Here You have to look at the source code to find out. Due to time constraints, here we know that the number of restores can be more than the number of saves. However, it is still recommended to restore less often than save to avoid unnecessary problems~ As for the process of entering and exiting the stack, I won’t talk about it. I drew it myself and it is very easy to understand!6. Explanation of saveLayer() and restoreToCount()
In fact, these two methods are similar to save and restore, but there are some more things based on the latter. Just the East, For example, saveLayer() has the following overloaded methods: You can understand that thesave() method saves the entire Canvas , and saveLayer() can selectively save the state of a certain area. In addition, we see that there is: int saveFlags in the room and board, this is the setting to change the object to be saved! Optional values are:
Tag | Description |
---|---|
##ALL_SAVE_FLAG | Save the entire state|
CLIP_SAVE_FLAG | Save the state of a cropped area|
CLIP_TO_LAYER_SAVE_FLAG | Save the status in the preset range|
Save Color coating | |
opaque layer save | |
Save the state of Matrix information (translate, rotate, scale, skew) |
CLIP_TO_LAYER_SAVE_FLAG
mode to write an exampleImplementation code
:RectF bounds = new RectF(0, 0, 400, 400); canvas.saveLayer(bounds, mPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.drawColor(getResources().getColor(R.color.moss_tide)); canvas.drawBitmap(bmp, 200, 200, mPaint); canvas.restoreToCount(1); canvas.drawBitmap(bmp, 300, 200, mPaint);Running result:
Let’s study it in detail later on saveLayer() ~Here is a general idea~
Then go to thisrestoreToCount(int)
, this is simpler, directly pass in the number of Layers to be restored, Jump directly to the corresponding layer, and at the same time kick all the Layers above the layer out of the stack, so that the layer Become the top of the stack~! It’s much more convenient and faster than writing multiple restore()~7. Download the code sample in this section:
Well, the code is written for testing, so there is no need to It doesn’t make sense, but maybe readers still want it, so just post the link!
Code download
:CanvasDemo.zipMaybe this is the picture you want! Haha~
Summary of this section: