• 风车控件, 光圈控件


    https://www.cnblogs.com/willhua/p/5763189.html

    参考大神的思路, 动手改造加深理解

    要点

    • 定义扇叶 (30, 60, 90 的直角三角形)
    • 找到内六边形顶点
    • 依次移动到顶点,进行旋转(参考第4幅图, 半透明是移动前的图形, 理解下面的计算)
      mPoints[0].x = curRadius / 2;
      mPoints[0].y = -curRadius * COS_30;

    布局文件:

    <?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.huawei.camera.canvas.MyTextView
            android:layout_width="100dp"
            android:layout_height="400dp" />
    
    </LinearLayout>

    代码参考:

    package com.huawei.camera.canvas;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PointF;
    import android.graphics.PorterDuff;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    
    public class MyTextView extends View {
        private static final String TAG = "MyTextView";
        private static final float ROTATE_ANGLE = 30;
        private static final int BACKGROUND_COLOR_ACTIVE = Color.parseColor("#FFFFFFFF");
        private static final float COS_30 = 0.866025f;
        private static final float MIN_RADIUS = 17.5f/COS_30;
        private static final float MAX_RADIUS = 67f/COS_30;
        private static final int SPACE = 3;
        private static final int BLADE_COLOR = Color.parseColor("#FF00FF00");
        private static final int VIRTUAL_BLADE_COLOR = Color.parseColor("#3300FF00");
    
        private int mCircleRadius;
        private int mWidth;
        private PointF[] mPoints = new PointF[6];
        private Bitmap mBlade;
        private Bitmap mVirtualBlade;
        private Bitmap mBmp;
        private Canvas mBmpCanvas;
        private Path mPath;
        private Paint mPaint;
        private int k = 0;
        public MyTextView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        class AnimationRotateRunnable implements Runnable {
            @Override
            public void run() {
                invalidate();
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            Log.i(TAG, "onDraw: " + getHeight());
            mBmpCanvas = canvas;
            mBmpCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);//清理画布, 防止透明背景出现叠加
            mBmpCanvas.drawColor(BACKGROUND_COLOR_ACTIVE);
            mBmpCanvas.save();
            calculatePoints(0);
            mBmpCanvas.translate(mWidth / 2, mWidth / 2);
            mBmpCanvas.rotate(k % 360);
            //mBmpCanvas.clipPath(mPath);
            for (int i = 0; i < 6; i++) {
                mBmpCanvas.save();
                mBmpCanvas.translate(mPoints[i].x, mPoints[i].y);
                mBmpCanvas.rotate(-i * 60);
                mBmpCanvas.drawBitmap(mBlade, 0, 0, mPaint);
                mBmpCanvas.restore();
            }
            //postInvalidateDelayed(20);
            mBmpCanvas.restore();
            mBmpCanvas.drawLine(0f, mWidth, mWidth, mWidth, mPaint);
    
            //2nd
            mBmpCanvas.save();
            calculatePoints(0.3f);
            mBmpCanvas.translate(mWidth / 2, 3 * mWidth / 2);
            //mBmpCanvas.clipPath(mPath);
            for (int i = 0; i < 6; i++) {
                mBmpCanvas.save();
                mBmpCanvas.translate(mPoints[i].x, mPoints[i].y);
                mBmpCanvas.rotate(-i * 60);
                mBmpCanvas.drawBitmap(mBlade, 0, 0, mPaint);
                mBmpCanvas.restore();
            }
            mBmpCanvas.restore();
            mBmpCanvas.drawLine(0f, 2*mWidth, mWidth, 2*mWidth, mPaint);
    
            //3rd
            mBmpCanvas.save();
            calculatePoints(0.6f);
            mBmpCanvas.translate(mWidth / 2, 5 * mWidth / 2);
            //mBmpCanvas.clipPath(mPath);
            for (int i = 0; i < 6; i++) {
                mBmpCanvas.save();
                mBmpCanvas.translate(mPoints[i].x, mPoints[i].y);
                mBmpCanvas.rotate(-i * 60);
                mBmpCanvas.drawBitmap(mBlade, 0, 0, mPaint);
                mBmpCanvas.restore();
            }
            mBmpCanvas.restore();
            mBmpCanvas.drawLine(0f, 3*mWidth, mWidth, 3*mWidth, mPaint);
    
            //4th
            mBmpCanvas.save();
            calculatePoints(0.9f);
            mBmpCanvas.translate(mWidth / 2, 7 * mWidth / 2);
            //mBmpCanvas.clipPath(mPath);
            mBmpCanvas.drawBitmap(mVirtualBlade, 0, 0, mPaint);
            for (int i = 0; i < 6; i++) {
                mBmpCanvas.save();
                mBmpCanvas.translate(mPoints[i].x, mPoints[i].y);
                mBmpCanvas.rotate(-i * 60);
                mBmpCanvas.drawBitmap(mBlade, 0, 0, mPaint);
                mBmpCanvas.restore();
            }
            mBmpCanvas.restore();
            k += 1;
        }
    
        private void calculatePoints(float progress) {
            if (mCircleRadius - SPACE <= 0) {
                Log.e(TAG, "the size of view is too small and Space is too large");
                return;
            }
            float curRadius = MIN_RADIUS + progress * (MAX_RADIUS - MIN_RADIUS);
            mPoints[0].x = curRadius / 2;
            mPoints[0].y = -curRadius * COS_30;
            mPoints[1].x = -mPoints[0].x;
            mPoints[1].y = mPoints[0].y;
            mPoints[2].x = -curRadius;
            mPoints[2].y = 0;
            mPoints[3].x = mPoints[1].x;
            mPoints[3].y = -mPoints[1].y;
            mPoints[4].x = -mPoints[3].x;
            mPoints[4].y = mPoints[3].y;
            mPoints[5].x = curRadius;
            mPoints[5].y = 0;
        }
    
        private void init() {
            mWidth = 350;
            mCircleRadius = 80;
            mBmp = Bitmap.createBitmap(mWidth, mWidth, Bitmap.Config.ARGB_8888);
            mBmpCanvas = new Canvas(mBmp);
            mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
            mPaint.setAntiAlias(true);
            for (int i = 0; i < 6; i++) {
                mPoints[i] = new PointF();
            }
            mPath = new Path();
            mPath.addCircle(0, 0, mCircleRadius, Path.Direction.CW);
            createBlade();
            createVirtualBlade();
        }
    
        private void createBlade() {
            mBlade = Bitmap.createBitmap(mCircleRadius,
                    (int) (mCircleRadius * 2 * COS_30), Bitmap.Config.ARGB_8888);
            Path path = new Path();
            Canvas canvas = new Canvas(mBlade);
            path.moveTo(SPACE / 2 / COS_30, SPACE);
            path.lineTo(mBlade.getWidth(), mBlade.getHeight());
            path.lineTo(mBlade.getWidth(), SPACE);
            path.close();
            canvas.clipPath(path);
            canvas.drawColor(BLADE_COLOR);
        }
    
        private void createVirtualBlade() {
            mVirtualBlade = Bitmap.createBitmap(mCircleRadius,
                    (int) (mCircleRadius * 2 * COS_30), Bitmap.Config.ARGB_8888);
            Path path = new Path();
            Canvas canvas = new Canvas(mVirtualBlade);
            path.moveTo(SPACE / 2 / COS_30, SPACE);
            path.lineTo(mVirtualBlade.getWidth(), mVirtualBlade.getHeight());
            path.lineTo(mVirtualBlade.getWidth(), SPACE);
            path.close();
            canvas.clipPath(path);
            canvas.drawColor(VIRTUAL_BLADE_COLOR);
        }
    }
    View Code

    变成光圈控件:

    只需要对canvas执行clipPath

  • 相关阅读:
    第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据
    第一百二十六节,JavaScript,XPath操作xml节点
    第一百二十五节,JavaScript,XML
    第一百二十四节,JavaScriptCookie与存储
    in_array严格模式和普通模式的区别
    thinkphp解决表单令牌问题
    php操作Memcache示例
    flash引入
    自己制作简单的可编辑并添加表情的文本编辑器
    php中mysqli 处理查询结果集的几个方法
  • 原文地址:https://www.cnblogs.com/hixin/p/9469262.html
Copyright © 2020-2023  润新知