directory

One, foreword

2. Calligrapher API in Canvas

Third, in actual combat

Write at the end

One, foreword

Canvas HAS a lot of API methods. Kids have shared “Pattern cutter in Canvas” and “Drawing Artist in Canvas” before this article, but today I will share the text API.

Before sharing, the children are verbose. Some children say that these articles of Canvas are primary articles and the words “Android advanced UI” seem to be somewhat incompatible. Children take this to explain, canvas’s several articles are as a supplement to advanced UI articles, is a stepping stone in this series of articles, not want to do “clickbait” to attract traffic (seems to have no traffic 😂).

Long winded so much, to see today’s actual combat renderings

Jitter character

2. Calligrapher API in Canvas

1, drawText (four overloaded methods)

(1) The first drawText function

public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
Copy the code

Description: Draws a text string at coordinates (x,y).

Here’s an example:

private static final String CONTENT = "Zinc's Fierce little friends.";

canvas.drawText(CONTENT, -300, -500, mPaint);
Copy the code

rendering (2) The second drawText function

public void drawText(@NonNull String text, int start, int end, float x, float y,
            @NonNull Paint paint)
Copy the code

Description: Draw the string text at coordinates (x,y), starting with characters with subscript start and ending with characters with subscript (end-1).

Here’s an example:

private static final String CONTENT = "Zinc's Fierce little friends.";

// Draw CONTENT from the fourth character of CONTENT to the last character of CONTENT
canvas.drawText(CONTENT, 3, CONTENT.length(), -300, -400, mPaint);
Copy the code

rendering (3) Third drawText function

public void drawText(@NonNull char[] text, int index, int count, float x, float y,
            @NonNull Paint paint)
Copy the code

Description: Draw text at coordinates (x,y), starting with subscript start, draw count characters.

For example

private static final char[] C = "https://github.com/zincPower/UI2018".toCharArray();

canvas.drawText(C, 0, C.length, -300, -100, mPaint);
canvas.drawText(C, 5.10, -300.0, mPaint);
Copy the code

rendering (4) The fourth drawText function

public void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
            @NonNull Paint paint)
Copy the code

Description: Draw text at coordinates (x,y), starting with characters with subscript start and ending with characters with subscript (end-1).

For example

private static final CharSequence SEQ = "https://blog.csdn.net/weixin_37625173";

canvas.drawText(SEQ, 0, SEQ.length(), -300.300, mPaint);
canvas.drawText(SEQ, 6.20, -300.400, mPaint);
Copy the code

rendering

2, drawTextOnPath (two overloaded methods)

(1) First drawTextOnPath function

public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
            float vOffset, @NonNull Paint paint)
Copy the code

Description: Draw text on path.

Special parameters are described as follows: 1) hOffset: indicates the horizontal offset. 2) vOffset: indicates the vertical offset

For example

private static final String CONTENT = "Zinc's Fierce little friends.";

// mPath is a path drawn by a Bezier curve
canvas.drawTextOnPath(CONTENT, mPath, 0.0, mPaint);
Copy the code

rendering (2) The second drawTextOnPath function

public void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
            float hOffset, float vOffset, @NonNull Paint paint)
Copy the code

Description: Draw text on path.

Special parameters are described as follows: 1) index: draws from the index character. 2) Count: indicates the number of characters to draw. 3) hOffset: indicates the horizontal offset

example

private static final char[] C = "https://blog.csdn.net/weixin_37625173".toCharArray();

// Draw 20 characters from the third character with subscript 2
canvas.drawTextOnPath(C, 2.20, mPath, 0.0, mPaint);
Copy the code

rendering

3, drawTextRun

This method will not be explained too much, because it is rarely used in real development. Briefly summarize the function of this method, he is to deal with some language characters (such as: Arabic), when a word in a word, will be affected by the word and deformation.

This aspect of the language children do not understand, so can not give a rigorous example, please have the need to move to the Demo experience.

public void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
            int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) 
            
public void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
            int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint)
Copy the code

4, drawPosText (two overloaded methods)

(1) First drawPosText function

public void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
            @NonNull Paint paint)
Copy the code

Description: Draw text on the coordinates of pos.

For example

private static final String CONTENT = "Fierce little Friend.";
private static final float[] pos1 = new float[]{
        -300, -600,
        -250, -500,
        -200, -400,
        -150, -300,
        -100, -200,
        -50, -100};// The pos coordinates of each character must correspond to one by one, otherwise crash
canvas.drawPosText(CONTENT, pos1, mPaint);
Copy the code

rendering (2) The second drawPosText function

public void drawPosText(@NonNull char[] text, int index, int count,
            @NonNull @Size(multiple = 2) float[] pos,
            @NonNull Paint paint)
Copy the code

Description: Draw text on the coordinates corresponding to pos, starting with the index character, draw count.

For example

private static final String CONTENT = "Fierce little Friend.";
private static final float[] pos2 = new float[]{
        -300.100,
        -250.200,
        -200.300,
        -150.400,
        -100.500}; canvas.drawPosText(CONTENT.toCharArray(),1.4, pos2, mPaint);
Copy the code

rendering

Third, in actual combat

Jitter character

Github portal: Portal

DrawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath: drawTextOnPath

To get points on a path, use the following function

private float calculateY(float x) {
    double a = Math.pow(4 / (4 + Math.pow(4 * x / mLength, 4)), 2.5 f) * mA;
    return (float) (a * Math.sin(Math.PI * x / 200 - m));
}
Copy the code

The specific function graph is as follows

The original prototype of the formula came from this blog, thanks to the blogger.

After reading this function, some children may be more meng force, children a little to give some simple explanation (after all, I can not say 😂), we will abstract this formula, is the following shape:

A*sin(w*x+m)+k
Copy the code

This is the trig function that we learned in junior high: the sine function sin. Let’s list the functions of several parameters:

  • A: Manage the amplitude of the sine function, that is, the amplitude of the oscillation up and down;
  • W: the horizontal contraction of the management sine function;
  • M: the horizontal offset of the management sine function;
  • K: vertical offset of the management sine function;

In our scenario, we control two parameters:

  1. The amplitude of A changes. In the above figure, the amplitude of the function vibrates larger near x=0, so we take the value of X into consideration in the calculation of A in the form of the denominator (the larger the denominator, the smaller the value; The smaller the denominator, the larger the value.)
  2. The horizontal offset of m, one period of the sine is 2 PI, so we only need a straight curve from 0 to 2 PI.

After the above simple analysis, we have all the parts we need, and finally add the familiar property animation to make the path move. Moving the path causes the text drawn on it to move.

mAnimator = ValueAnimator.ofFloat(0, (float) (2 * Math.PI));
mAnimator.setInterpolator(new LinearInterpolator());
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float progress = (float) animation.getAnimatedValue();
        m = progress;
        mA = (float) (1 - progress / (2* Math.PI)) * A; invalidate(); }}); mAnimator.setDuration(1000);
Copy the code

Write at the end

This article is relatively simple and basic, but children are a little obsessive, so they must go through and record every API of Canvas.

If you find this article enlightening, please give me a thumbs up. If you find any problems, please discuss with me in the comments section, and we will make progress together.

Advanced UI series Github address: please enter the portal, if you like to give me a star bar 😄