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

先看效果图

这里写图片描述

代码

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;
    }

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值