Android uses the graphics.Camera class to implement custom rotation and fall

        I'm a novice and this is my first blog. There are references to the blogs of individual senior gods in the text. If there is any infringement, please let me know and I will deal with it as soon as possible.

need:

        Some time ago, there was a need: to make a parkour-like streamer scattered animation effect.

research:

        According to the initial idea + the vague suggestions of colleagues, I collected a bunch of snowflake effects on the Internet. It is found that it does not meet the demand, and most of the cases on the Internet are the falling effect of the plane. A little nimbleness (rotation) is missing. I found a good thing by chance in a query data: Use Camera to achieve 3D rotating and falling effect Blog: Imitate the purse to start the animation Click to open the link . Found a nice graphics.Camera class that has never been used before. Camera can realize the rotation effect that ordinary snowflakes do not have, and the specific introduction and use of this will not be introduced. Friends who need to know more about it will find a Du Niang by themselves.

idea:

        The original idea was to synthesize the rotation effect of the Camera into an existing snowflake project on the Internet. Because the two projects are not written by themselves encountered some difficulties. Finally, I chose to go step by step and use my own custom view to implement it.

    1. Write a FallView that inherits View to realize the rotation and falling of a single snowflake picture.

    2. Write a SnowFallView that inherits RelativeLayout to store List<FallView> to achieve the effect of multiple snowflake pictures falling.

accomplish:

        Note: Due to my limited level, there are no in-depth issues that have not been considered for performance optimization. Just to achieve results.

        Due to time problems and insufficient code maturity, this article only talks about the implementation of the first point of FallView, directly to the code, with detailed comments in it

package com.walke.anim.camera;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.walke.anim.R;

/**
 * Created by walke.Z on 2018/4/20.
 * Snow falling effect:
 * 1, single falling effect
 * a.onDraw uses the canvas.drawBitmap() method to draw snowflakes
 * b. Change the drawing position to achieve animation effect
 */

public class FallView extends View {

    private Bitmap mSnow;

    /**
     * Control width
     */
    private int mWidth;
    /**
     * Control height
     */
    private int mHeight;

    /**
     * Brush
     */
    private Paint mPaint;
    /**
     *
     */
    private float mX1;
    /**
     *
     */
    private float mY1 = 0;

    /**
     * Classes in the graphics package to implement rotation
     */
    Camera mCamera;
    /**
     * Falling speed
     */
    private float mSpeed = 1.5f;

    public FallView(Context context) {
        this(context, null);
    }

    public FallView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FallView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mSnow = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.image_snow_96);
        mPaint = new Paint();
        mCamera = new Camera();
    }

    private void resizeBitmap(float scale) {
        Matrix m = new Matrix();
        m.setScale(scale, scale);
        mSnow = Bitmap.createBitmap(mSnow, 0, 0, mSnow.getWidth(), mSnow.getHeight(), m, true);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        mX1 = (mWidth - mSnow.getWidth()) / 2;
    }

    private float degrees = 0;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // use graphics.Camera -------
        Matrix mMatrix = new Matrix();
        mCamera.save(); // Record the initial state. save() and restore() can make the transition of the image softer.

        //Rotation angle
        if (degrees < 360) {
            degrees += 6;
        } else {
            degrees = 0;
        }
        mCamera.rotateY(degrees);

        // pan--fall
        if (mY1 > -(mHeight - mSnow.getHeight())) {
            mY1 -= mSpeed;//Note here is -
        }
        mCamera.translate(mX1, mY1, 0);// mY1: -50


        mCamera.getMatrix(mMatrix);
        int centerX = (mWidth) / 2;
        int centerY = mSnow.getHeight() / 2;

        mMatrix.preTranslate(-centerX, -centerY);
        mMatrix.postTranslate(centerX, centerY);

        mCamera.restore();
//        Log.i("walke", "FallView draw: -------> mX1 = "+mX1+" ---> mY1 = "+mY1 );
        canvas.drawBitmap(mSnow, mMatrix, mPaint);// The drawing starts from the upper left corner

        // The following two lines of code can be used for the downward application of ordinary pictures
        // canvas.drawBitmap(mSnow, mX1, mY1, mPaint);// The drawing starts from the upper left corner
        // mY1+=2;

        invalidate();//60 frames per second
    }
}

Layout use:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <com.walke.anim.camera.FallView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#79a1f7"/>


</LinearLayout>

Screenshot of the effect picture, no gif picture

       



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324693283&siteId=291194637