Custom Controls (3): Canvas effect Conversion
Canvas
We have learned from the above that the Canvas class can draw various shapes.
Here, let's take a look at the transform effect of the Canvas class (translation, rotation, etc)
First, you need to know about the Canvas. When we use the Canvas. DrawXXX () method, it is not drawn on a Canvas. InsteadEvery time you call the. DrawXXX () method, a new canvas is generated and drawn on it. This is similar to the layers in PS..
The explanation is shown below.
1. offset (. translate)
That is to say, let the canvas translate, and the above painting operation will also follow the translation
Public void translate (float dx, float dy); // canvas offset
Float dx: the translation distance in the horizontal direction. A positive number refers to the number of translation in the positive direction (to the right), and a negative number refers to the number of translation in the negative direction (to the left). flaot dy: the distance to the vertical direction. A positive number is the number to be shifted to the positive direction (down). A negative number is the number to be shifted to the negative direction (up ).
Paint paint = new Paint (); paint. setStyle (Paint. style. FILL); paint. setColor (Color. RED); paint. setStrokeWidth (2); // first draw a rectangular canvas with the coordinates (100,100) in the upper left corner and a width (300) and a height (200. drawRect (100,100,400,300, paint); // pan the canvas. translate (120,120); paint. setColor (Color. BLACK); // draw a rectangle with a width of 300 and a height of 200, because the canvas Pan 120px to the right and 120px down, // The distance from the upper left corner of the screen is (100 + 120,100 + 120) canvas. drawRect (100,100,400,300, paint );
The Green Box is the position of the new canvas after the translation (100,100 ).
The black rectangle is drawn at the origin in the upper left corner of the new canvas position (Green Box) (100,100 ).
Note that the position of each canvas drawn by drawXXX is subject to the new canvas. For example, I will draw another rectangle.
Paint paint = new Paint (); paint. setStyle (Paint. style. FILL); paint. setColor (Color. RED); paint. setStrokeWidth (2); // first draw a rectangular canvas with the coordinates (100,100) in the upper left corner and a width (300) and a height (200. drawRect (100,100,400,300, paint); // pan the canvas. translate (120,120); paint. setColor (Color. BLACK); // draw a rectangle with a width of 300 and a height of 200, because the canvas Pan 120px to the right and 120px down, // The distance from the upper left corner of the screen is (100 + 120,100 + 120) canvas. drawRect (100,100,400,300, paint); // draw a blue rectangle to see whether the rectangle is based on the source in the upper left corner of the canvas before the pan or the source painting in the upper left corner of the pan. setColor (Color. BLUE); canvas. drawRect (200,200,500,400, paint );
It can be seen that after the conversion (translation, rotation, etc.) operation is performed on the canvas, the new canvas position prevails in the drawXXX operation.
So, for example, I only want to translate the canvas where the second rectangle is located, and the canvas is the original one. What should I do? Do we still need to perform reverse operations, how can I translate it back?
Actually, the Canvas class has two methods:
Canvas. save (); // save the canvas status (location, etc.) to the canvas in the stack. restore (); // obtain the top-most canvas status in the stack and restore the current canvas according to the status.
Example:
Paint paint = new Paint (); paint. setStyle (Paint. style. FILL); paint. setColor (Color. RED); paint. setStrokeWidth (2); // first draw a rectangular canvas with the coordinates (100,100) in the upper left corner and a width (300) and a height (200. drawRect (100,100,400,300, paint); canvas. save (); // save the current canvas status // pan the canvas. translate (120,120); paint. setColor (Color. BLACK); // draw a rectangle with a width of 300 and a height of 200, because the canvas Pan 120px to the right and 120px down, // The distance from the upper left corner of the screen is (100 + 120,100 + 120) canvas. drawRect (100,100,400,300, paint); canvas. restore (); // restore to the canvas state saved on the top of the stack // draw a blue rectangle, check whether the rectangle is based on the source point in the upper left corner of the canvas before the translation or the painting at the upper left corner of the canvas after the translation. setColor (Color. BLUE); canvas. drawRect (200,200,500,400, paint );
As you can see, the red rectangle is drawn on the original canvas, and then the status of the original canvas is saved,
Translate the canvas (100,100) to draw a black rectangle, and then restore the canvas status to the Saved state at the top of the stack.
At this time, draw a blue rectangle and you will find that the blue rectangle is drawn on the original canvas.
Ii. rotating (. rotate)
Public void rotate (float degrees) public void rotate (float degrees, float px, float py)
The first constructor directly inputs the degree of rotation. The positive value is clockwise and the negative value is clockwise. its center point is the origin (0, 0)
In addition to degrees, the second constructor can also specify the coordinates of the center (px, py) of the rotation)
Paint paint = new Paint (); paint. setStyle (Paint. style. FILL); paint. setColor (Color. RED); paint. setStrokeWidth (2); // first draw a rectangular canvas with the coordinates (100,100) in the upper left corner and a width (300) and a height (200. drawRect (200,200,400,300, paint); // rotate the canvas. rotate (15); // controls the rotation angle, clockwise painting. setColor (Color. BLACK); // draw a rectangle with a width of 300 and a height of 200, because the canvas Pan 120px to the right and 120px down, // The distance from the upper left corner of the screen is (100 + 120,100 + 120) canvas. drawRect (200,200,400,300, paint );
Iii. scale)
Public void scale (float sx, float sy) sx: horizontal scaling
Sy: Vertical Scaling
Unit float,> 1 indicates expansion, <1 indicates reduction = 1 indicates not change
Paint paint = new Paint ();
Paint. setStyle (Paint. Style. FILL );
Paint. setColor (Color. RED );
Paint. setStrokeWidth (2 );
// Draw a rectangle with the coordinates (100,100) in the upper left corner and 300 in width and 200 in height.
Canvas. drawRect (400,300, paint );
// Scale the canvas
Canvas. scale (0.5f, 0.5f); // halved
Paint. setColor (Color. BLACK );
// Draw a rectangle with a width of 300 and a height of 200, because the canvas has shifted 120px to the right and 120px to the bottom,
// The distance from the upper left corner of the screen is (100 + 120,100 + 120)
Canvas. drawRect (400,300, paint );
4. skew (. skew)
Public void skew (float sx, float sy) float sx: Tilt the canvas to the corresponding angle in the x direction, the tan value of the sx skew angle, float sy: tilt the canvas to the corresponding angle on the Y axis. sy is the tan value of the tilt angle,
Note: The tan value of the skew angle, for example, 60 degrees of skew, tan60 = root number 3, decimal number corresponding to 1.732, then the parameter is 1.732
Paint paint = new Paint (); paint. setStyle (Paint. style. FILL); paint. setColor (Color. RED); paint. setStrokeWidth (2); // first draw a rectangular canvas with the coordinates (100,100) in the upper left corner and a width (300) and a height (200. drawRect (400,300, paint); // scale the canvas. skew (1.732f, 0); // zoom in half to paint. setColor (Color. BLACK); canvas. drawRect (400,300, paint );