Gtihub portal

directory

  1. Real cool custom View (1)
  2. Custom View (2)
  3. Custom View (3)

Advanced use of Canvas

In my Github open source library, today just wrote a pie chart drawing, here is mainly on the pie chart drawing a explained.

We’ve talked about a Path before, but if you implement it all with Path, that’s not to say you can’t implement it, but it doesn’t work for many scenarios.

Here, we are mainly talking about the use of Canvas. Previously we used a function called moveTo in Path to move the Path from its current location to a new coordinate. Does our Canvas have such a function?

Translate translate translate translate translate translate translate translate translate translate translate translate This function is a relative movement, not an absolute one.

canvas? .translate(60f, 80f) paint? .let { canvas? .drawCircle(0f, 0f, 100f, it) } canvas? .translate(60f, 80f)paint? .color = Color.BLUE paint? .let { canvas? .drawCircle(0f, 0f, 100f, it) }
Copy the code

That’s the implementation code and a texture. You can intuitively feel that the movement is actually done on the current basis. But the reader will say, I can do it with Path, not Canvas, ok, you can do it with Path.

But the difficulty is now, how to implement the style below?

Before we know how to write code, we need to know what it’s definitely made of.

  1. A combination of two lines. Intuitively, this polyline should be a combination of two lines
  2. A combination of two lines. That’s description four and 6.0% in the picture

Wouldn’t it be too much trouble if we just went and got absolute coordinates and drew them? So we’re going to introduce a Canavs operation here.

Canvasoperation

Before using it, note that the canvas needs to be saved, otherwise the canvas will continue to retain the state of the last drawing, and the whole will present a superimposed chaotic situation. This method is a pair of save() and restore().

for (i in 0.2.) { canvas? .save() paint? .color = Color.BLUE canvas? .translate(60f, 80f) canvas? .scale(0.5f, 0.5f) paint? .let { canvas? .drawCircle(0f, 0f, 100f, it) } canvas? .restore() }Copy the code
Before using After using

You can think of this operation as a canvas return, or canvas reset. This reset corresponds to saving the operation before save().

Scale

This effect will not be repeated.

Rotate

Just like everything else there are two kinds of canvas manipulation functions

  1. Rotate (float degrees, float px, float py) is a custom rotation center
  2. Rotate (float degrees), the current position of the canvas as the center of the rotation circle
canvas? .save() paint? .color = Color.BLUE canvas? .translate(60f, 80f) canvas? .rotate(45f)
// Rotate with its center as a dot
// canvas? .rotate(45f,30f, 40f)paint? .let { canvas? .drawRect(0f, 0f, 100f, 100f, it) } canvas? .restore()Copy the code

Pie chart implementation is actually based on this function to complete.

Shew

And unlike the others, instead of going through the center of our coordinates, he’s going to map our X and Y axes

canvas? .save() paint? .color = Color.BLUE canvas? .translate(60f, 80f) canvas? .skew(0f, 1f) paint? .let { canvas? .drawRect(0f, 0f, 100f, 100f, it) } canvas? .restore()Copy the code

The data passed in is essentially the tangent of the X and Y axes, which you can see clearly with the screenshot tool. With the green box, you can see that it’s exactly 45 degrees.

Or you can view it this way, just by drawing it, that the Y axis is rotated 45 degrees clockwise.

The basic idea of pie chart drawing

  1. How is the circle compatible with the text, this is a difficult point, I can only say that after many attempts, the width of the circle is 0.3 times the most appropriate. Because 0.5 times is exactly full; 0.4 times, text too small. You can make your own changes to this value.
  2. I told you how to draw lines. The layout of the text must have changed directly according to the introduction line, which is the most important point.
  3. How to change the color of the arc.

Basically, the above questions. I have answered question 1 and will explain the following two questions one by one.

How to draw the introduction line

In my code, actually divided into two, one is the arc, one is the introduction, which is also their drawing order. But there is a question to consider: where are the introductory lines located?

You need to look at my legend for this question. Have you noticed that my introduction line seems to be all about a single arc centered?

So here’s our solution. What did we say? Rotate remembers this function. Now that we have the size of each arc, can’t we draw it? I thought it was scribing and then spinning. And then the rotation is a formula like this to compute.

// Rotation Angle = front radian + half of current radian
private fun getRatioSum(j: Int): Float {
        var sum = 0f
        for (i in 0until j) { sum += mRatios!! [i] }return sum
    }

    private fun getRatioHalfSumDegrees(j: Int): Float {
        varsum = getRatioSum(j) sum += mRatios!! [j] /2
        return sum * 360
    }
Copy the code

How does the arc change color

The arcs are the same as the previous ones, but they form a circle one by one. In this case, it is necessary to know the radians in front, and then calculate the current radians, that is, the swept interval.

private fun drawArc(canvas: Canvas) {
        val drawArc = 360 * scale
        for (i inmRatios!! .indices) { mArcPaint? .color = mArcColors!! [i] mArcPaint? .let { canvas.drawArc( arcRect!! , getRatioSum(i) * drawArc, mRatios!! [i] * drawArc,true,
                    it
                )
            }
        }
    }
Copy the code

Basically it is to rely on the above two to complete, is it still relatively simple. Go ahead, copy the Demo, and you have your own pie chart to draw.