Canvas模拟太阳地球月球的运动过程

2019-04-14 20:56发布

先看效果图

这里写图片描述

代码

package com.test.paintdemo.pathrelate; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathMeasure; import android.graphics.RadialGradient; import android.graphics.Shader; import android.view.View; import com.test.paintdemo.R; /** * Created by ygdx_lk on 17/6/23. */ public class PlanetCircle extends View { private Paint mPaintCircle, mPaintSun, mPaintOne, mPaintTwo; private final Bitmap mBitmap; private float fraction_earth; private float fraction_moon; private static final String TAG = "PlanetCircle"; private int mViewWidth, mViewHeight; public PlanetCircle(Context context) { super(context); //轨道画笔 mPaintCircle = new Paint(); mPaintCircle.setStyle(Paint.Style.STROKE); mPaintCircle.setColor(Color.GRAY); mPaintCircle.setStrokeWidth(3); mPaintCircle.setAntiAlias(true); //太阳 mPaintSun = new Paint(); mPaintSun.setColor(Color.RED); mPaintSun.setStyle(Paint.Style.FILL); mPaintSun.setAntiAlias(true); //地球 mPaintOne = new Paint(); mPaintOne.setAntiAlias(true); //月亮 mPaintTwo = new Paint(); mPaintTwo.setAntiAlias(true); //图片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 12; // 缩放图片 mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mViewWidth = w; mViewHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); //画布平移 canvas.translate(mViewWidth / 2, mViewHeight / 2); //1.画轨道 Path path = drawPlanetPathWayOval(canvas, - getWidth() / 3, - getWidth() / 4, getWidth() / 3, getWidth() / 4); //2.画太阳 drawSun(canvas); //绘制图片 drawBitmap(canvas, path, fraction_earth); //3.画地球及月球 drawPlanetEarth(canvas, path); //4.转动 startAnim(); } /** * 启动动画 */ private void startAnim() { fraction_earth += 0.003; if(fraction_earth >= 1){ fraction_earth = 0; } fraction_moon += 0.006; if(fraction_moon >= 1){ fraction_moon = 0; } invalidate(); } /** * 画图片 * @param canvas */ private void drawBitmap(Canvas canvas, Path path, float fraction){ PathMeasure measure = new PathMeasure(path, false); Matrix mMatrixBitMap = new Matrix(); //获取角度和路径 measure.getMatrix(measure.getLength() * fraction, mMatrixBitMap, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG); // 将图片绘制中心调整到与当前点重合(注意:此处是前乘pre) mMatrixBitMap.preTranslate(- mBitmap.getWidth() / 2, - mBitmap.getHeight() / 2); canvas.drawBitmap(mBitmap, mMatrixBitMap, mPaintCircle); } /** * 画月球 * @param canvas * @param mPath2 * @param fraction */ private void drawPlanetMoon(Canvas canvas, Path mPath2, float fraction) { PathMeasure pathMeasure2 = new PathMeasure(); float[] pos2 = new float[2]; float[] tan2 = new float[2]; Matrix matrix2 = new Matrix(); //测量坐标和角度 pathMeasure2.setPath(mPath2, false); pathMeasure2.getPosTan(pathMeasure2.getLength() * fraction, pos2, tan2); //设置shader matrix2.setRotate(360 * fraction); RadialGradient mRadialGradient2 = new RadialGradient(pos2[0], pos2[1], 30, new int[]{0x0000FF00, 0xFF00FF00}, null, Shader.TileMode.MIRROR); mPaintTwo.setShader(mRadialGradient2); mRadialGradient2.setLocalMatrix(matrix2); //绘制月球 canvas.drawCircle(pos2[0], pos2[1], 30, mPaintTwo); } /** * 画地球 * @param canvas */ private void drawPlanetEarth(Canvas canvas, Path path1) { PathMeasure pathMeasure1 = new PathMeasure(); float[] pos1 = new float[2]; float[] tan1 = new float[2]; Matrix matrix1 = new Matrix(); //测量坐标和角度 pathMeasure1.setPath(path1, false); pathMeasure1.getPosTan(pathMeasure1.getLength() * fraction_earth, pos1, tan1); //旋转shader matrix1.setRotate(360 * fraction_earth); RadialGradient mRadialGradient1 = new RadialGradient(pos1[0] + 10, pos1[1] + 10, 50, new int[]{0x000000FF, 0xFF0000FF}, null, Shader.TileMode.MIRROR); mPaintOne.setShader(mRadialGradient1); mRadialGradient1.setLocalMatrix(matrix1); //画地球 canvas.drawCircle(pos1[0], pos1[1], 50, mPaintOne); //---画地球的卫星月球-------------- //画月球圆形轨道 Path path = drawPlanetPathWayCircle(canvas, pos1[0], pos1[1], 100); //画图片 drawBitmap(canvas, path, fraction_moon); //画月球 drawPlanetMoon(canvas, path, fraction_moon); } /** * 画太阳 */ private void drawSun(Canvas canvas) { //创建Shader RadialGradient mRadialGradientSun = new RadialGradient(20, 20, 100, new int[]{0x00ff0000, 0xffff0000}, null, Shader.TileMode.MIRROR); //创建Matrix Matrix matrixSun = new Matrix(); //旋转 matrixSun.setRotate(360 * fraction_earth); //Shader设置Matrix mRadialGradientSun.setLocalMatrix(matrixSun); //画笔设置Shader mPaintSun.setShader(mRadialGradientSun); //绘制太阳 canvas.drawCircle(0, 0, 100, mPaintSun); } /** * 绘制圆圈路径 * @param canvas 画笔 * @param x 圆心X坐标 * @param y 圆心Y坐标 * @param radius 圆半径 */ private Path drawPlanetPathWayCircle(Canvas canvas, float x, float y, int radius){ Path path = new Path(); //画圆 path.addCircle(x, y, radius, Path.Direction.CW); canvas.drawPath(path, mPaintCircle); return path; } /** * 绘制椭圆路径 * @param canvas * @param left * @param top * @param right * @param bottom * @return */ private Path drawPlanetPathWayOval(Canvas canvas, float left, float top, float right, float bottom){ Path path = new Path(); //画椭圆 path.addOval(left, top, right, bottom, Path.Direction.CW); canvas.drawPath(path, mPaintCircle); return path; } }