I am participating in the Mid-Autumn Festival Creative Submission contest, please see: Mid-Autumn Festival Creative Submission Contest for details

Come ~ ceng Mid-Autumn festival heat to ~

LunarPhase

AKA phases of the moon. What are the phases of the moon? About the phases of the moon, this article is only half drawn, i.e. from new moon to full moon.

Project address: LunarPhase << Click on a gay dating site

preview

I recorded it at 1 o ‘clock in the morning. I couldn’t bear it anymore. I just came to fill this article today.

implementation

I’ll show you a picture of an ellipse, and I’ll show you how it works

If the length of the Major axis is equal to the length of the Minor axis, it is a perfect circle.

Now, use your imagination and fix the Major axis and change the Minor axis values. This is a changing ellipse, and then a semicircle. The merged figure will block a perfect circle.

Hahaha ~ Now comes the core code and comments. I think you can understand them all.

override fun onDraw(canvas: Canvas) {super.ondraw (Canvas) // Canvas. DrawColor (contextCompat.getColor (context!! , android.R.color.black)) val rectF = RectF(0f, 0f, width.toFloat(), height.toFloat()) paint.color = ContextCompat.getColor(context!! , android.r.color. holo_orange_light) val radius = min(width, height) * 0.3f canvas. DrawCircle (rectf.centerx (), rectF.centerY(), radius, paint) val c = canvas.saveLayer( RectF(0f, 0f, width.toFloat(), height.toFloat()), null, Canvas.ALL_SAVE_FLAG ) paint.isDither = true paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER) // The following calculations are related to how the mPhase changes // First the mPhase is modified by CountDownTimer // Create a rectangle, Fixed center in the middle of the screen val rectFOval = when {mPhase > 150 -> {// here the ellipse 'Minor axis' is in the smaller minion -> minion RectF(rectf.centerx () - radius *  (mPhase - 150) / 150, rectF.centerY() - radius, rectF.centerX() + radius * (mPhase - 150) / 150, Rectf. centerY() + radius)} mPhase < 150 -> {// Here the ellipse 'Minor axis' is getting larger. RectF(rectf.centerx () - (radius-radius * mPhase / 150), rectf.centery () - radius, rectF.centerX() + (radius - radius * mPhase / 150), rectF.centerY() + radius ) } else -> { null } } val rectFCircle = RectF( rectF.centerX() - radius, rectF.centerY() - radius, rectF.centerX() + radius, rectF.centerY() + radius ) paint.color = ContextCompat.getColor(context!! , android.R.color.black) when { mPhase == 150 -> { if (rectFOval ! = null) { canvas.drawOval(rectFOval, paint) } canvas.drawArc(rectFCircle, 90f, 180f, false, Paint) mPhase == 0 -> {mPhase < 150 -> { DrawArc (rectFCircle, 90F, 180F, false, paint) // As the length of the 'Minor axis' decreases by 0, then increases. Paint. Xfermode = PorterDuffXfermode(porterduff.mode.dst_out) canvas. DrawOval (rectFOval!! , paint) } else -> { canvas.drawOval(rectFOval!! , paint) canvas.drawArc(rectFCircle, 90f, 180f, false, paint) } } paint.xfermode = null canvas.restoreToCount(c) Log.d("LunarPhase", "mRotate=$mRotate") // Rotate the canvas. For recording preview. canvas.rotate(mRotate.toFloat()) }Copy the code

The PorterDuffXfermode used in this paper is supplemented with a graph, the relation between semicircle and ellipse and the relation between lunar phase change

Pseudocode for this graph

DrawColor () // CLEAR drawCiricle() // draw circle, DST paint. Xfermode = *** drawRect() // draw square, SRCCopy the code

I used two of them here

  • PorterDuff.Mode.DST_OVER

As can be seen from the figure above, the result of DST_OVER is the combination of square and circle, with the circle on top. In our code, that is, the combination of semicircle and ellipse, and then with our background, that is, to achieve the change of the moon.

  • PorterDuff.Mode.DST_OUT

As can be seen from the figure, the knot shown by DST_OUT is eroded by a square bar circle, and only part of the circle after erosion is displayed. In our code, that is, the ellipse eroded the semicircle, and then with our background, that is, the waxing gibbous moon change. Because of the relationship of erosion, the order of drawing here is very important. Draw the semicircle first, so that the eroded part of the semicircle can be retained.

conclusion

Writing code is really fun ~ ~ some knowledge points, put down for a period of time and then pick up maybe you will have a new understanding. Consider the old and learn the new.

Today is Teachers’ Day 2021 ~ Happy Teachers’ Day to all teachers and friends who are teachers themselves