This is the sixth day of my participation in Gwen Challenge
Welcome to follow my public account “ananzhuo”, learn more knowledge
Read a good book. – I said
The previous articles covered Canvas, Paint, and Path, which are commonly used in custom controls. In this article we go one step further on the basis of the previous several, drawing an underwater world effect.
Github address of the project
Github.com/ananananzhu…
Drawing process
Draw the background
SetShader: Draw the entire Canvas using the canvas. drawRect method. Paint sets a Shader as follows:
paintBack.shader = LinearGradient(
measuredWidth / 3f,
0f,
measuredWidth * 2 / 3f,
measuredHeight.toFloat(),
Color.WHITE,
Color.parseColor("#000055"),
Shader.TileMode.CLAMP
)
Copy the code
canvas.drawRect(background, paintBack)
Copy the code
It looks something like this
Draw a whale
Cough, whale this thing I found a picture in Baidu
After that, the most beautiful blue whale was pulled out with PS, and the tail of the blue whale was processed with PS liquefaction tool. The purpose is to make the tail of the blue whale swing constantly during the movement so as to achieve the effect of swimming
Code:
private val bitmaps = listOf<Bitmap>(
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish1),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish2),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish3),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish4),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish3),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish2),
BitmapFactory.decodeResource(context.resources, R.drawable.bluefish1),
)
Copy the code
canvas.run {
drawBitmap(bitmaps[bitmapIndex % bitmaps.size], 100f, 100f, paint)
bitmapIndex++
drawFishWithPath()
}
Copy the code
Effect:
It’s not enough for the killer whale to swing its tail. We should also make it swim, and it’s best to follow our designated path
The core code that defines the path
fishPath.moveTo(100f, 100f) for (i in 0.. 20) { fishPath.apply { cubicTo(randowX(), randowY(), randowX(), randowY(), randowX(), randowY()) } } fishPath.close()Copy the code
Draw the path effect
There is a problem here, because there are a lot of sharp angles when the path turns, which can not be expected, and the baby killer whale will not swim in this way, right? This will be optimized later, the most important thing is to achieve the effect
Let the fish move along the path
This is where the PathMeasure tool comes in
dstPath.reset() var stop = start+100f pathMeasure.getSegment(start, stop, dstPath, true) val matrix = Matrix() pathMeasure.getMatrix(stop, matrix, (PathMeasure.POSITION_MATRIX_FLAG.or(PathMeasure.TANGENT_MATRIX_FLAG))) val bitmap = bitmaps[bitmapIndex % bitmaps.size] matrix.preTranslate(-bitmap.width / 2f, -bitmap.height / 2f) canvas.drawBitmap(bitmap, matrix, paint)Copy the code
The code can intercept the path through the pathMeasure. GetSegment method to draw a whale picture at a certain position of the path. Because we can get the tangent value of a certain point of the path, our whale can always swim along the tangent line
Swimming effect:
Unfortunately, I forgot to record the screen in the middle and had to put up the final image
Draw the sun and bubbles
Now that we have the final effect, let’s go ahead and put in the sun and bubble code
Draw the sun
The main point of painting the sun is to paint the surrounding sunlight. When we draw sunlight, we divide the sun into 20 equal radians, and then triangle outward between the two equal points to achieve our sunshine effect.
Path.moveto (radius + sunX, sunY) val degree = 3.14f * 2 / leafNum for (I in 1.. LeafNum) {val x1 = radius * cos(I * degree) + sunX val y1 = radius * sin(I * degree) + sunY val halfDegree = (i-0.5) * degree val shineRadius = radius + Random.nextInt(50) val controllX = shineRadius * cos(halfDegree).toFloat() + sunX val controllY = shineRadius * sin(halfDegree).toFloat() + sunY path.lineTo(controllX, controllY) path.lineTo(x1, y1) } path.close()Copy the code
Draw air bubbles
We use RadiaGradient image gradient way to achieve bubble effect, to pay attention to the point is the image gradient color middle point do not choose in the center of the circle, otherwise it will be very ugly
paint.shader=RadialGradient(cycleX+40,cycleY-40,radius+300, Color.WHITE,Color.GREEN,Shader.TileMode.CLAMP)
canvas.drawCircle(cycleX, cycleY, radius, paint)
Copy the code