国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

波浪圖

2019-11-09 14:34:40
字體:
來源:轉載
供稿:網友

前幾天擼了個貝塞爾曲線,最近看到波浪圖很敢興趣,想著也是貝塞爾曲線。真實做的時候使用的不是貝塞爾但是也是數學公式。其實貝塞爾曲線一樣能做出來。

注意看那個淺紅色部分。特意使用顏色不一樣的


WaveView,主要靠做bitmap然后通過正弦直接看代碼

public class WaveView extends View { //*************屬性開始**************// /** * 振幅比例 */ PRivate static final float DEFAULT_AMPLITUDE_RATIO = 0.05f; /** * 水位比例 */ private static final float DEFAULT_WATER_LEVEL_RATIO = 0.5f; /** * 波長比例 */ private static final float DEFAULT_WAVE_LENGTH_RATIO = 1.0f; /** * 偏移 */ private static final float DEFAULT_WAVE_SHIFT_RATIO = 0.0f; /** * 后面波浪的顏色 */ public static final int DEFAULT_BEHIND_WAVE_COLOR = Color.parseColor("#28FFFFFF"); /** * 前面波浪的顏色 */ public static final int DEFAULT_FRONT_WAVE_COLOR = Color.parseColor("#3CFFFFFF"); /** * 外觀樣式 */ public static final ShapeType DEFAULT_WAVE_SHAPE = ShapeType.CIRCLE; public enum ShapeType { CIRCLE, SQUARE } /** * 是否展示波浪動畫 */ private boolean mShowWave; /** * 著色器 */ private BitmapShader mWaveShader; /** * shader矩陣 */ private Matrix mShaderMatrix; /** * view的畫筆 */ private Paint mViewPaint; /** * 邊界border的畫筆 */ private Paint mBorderPaint; /** * 默認振幅 */ private float mDefaultAmplitude; /** * 默認水位 */ private float mDefaultWaterLevel; /** * 默認wave寬度 */ private float mDefaultWaveLength; /** * 默認波浪角頻率 */ private double mDefaultAngularFrequency; /** * 默認振幅比例 */ private float mAmplitudeRatio = DEFAULT_AMPLITUDE_RATIO; /** * 波浪寬度 */ private float mWaveLengthRatio = DEFAULT_WAVE_LENGTH_RATIO; /** * 波浪水位 */ private float mWaterLevelRatio = DEFAULT_WATER_LEVEL_RATIO; /** * 位移 */ private float mWaveShiftRatio = DEFAULT_WAVE_SHIFT_RATIO; /** * 默認后面波浪顏色 */ private int mBehindWaveColor = DEFAULT_BEHIND_WAVE_COLOR; /** * 默認前面波浪顏色 */ private int mFrontWaveColor = DEFAULT_FRONT_WAVE_COLOR; /** * 默認著色外觀 */ private ShapeType mShapeType = DEFAULT_WAVE_SHAPE; //*************屬性結束**************// public WaveView(Context context) { super(context); init(); } public WaveView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public WaveView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } /** * 做一些初始化的操作 */ private void init() { mShaderMatrix = new Matrix(); mViewPaint = new Paint(); mViewPaint.setAntiAlias(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); createShader(); } /** * 繪制初始波形 */ private void createShader() { mDefaultAngularFrequency = 2.0f * Math.PI / DEFAULT_WAVE_LENGTH_RATIO / getWidth(); //默認振幅()= 控件的高度* 默認振幅比例 mDefaultAmplitude = getHeight() * DEFAULT_AMPLITUDE_RATIO; mDefaultWaterLevel = getHeight() * DEFAULT_WATER_LEVEL_RATIO; mDefaultWaveLength = getWidth(); //創建長寬恰等于WaveView的Bitmap Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint wavePaint = new Paint(); wavePaint.setStrokeWidth(2); wavePaint.setAntiAlias(true); //把波浪畫到bitmap上面 //畫一個正弦曲線 // y=Asin(ωx+φ)+h final int endX = getWidth() + 1; final int endY = getHeight() + 1; float[] waveY = new float[endX]; //初始化后面波浪 wavePaint.setColor(mBehindWaveColor); for (int beginX = 0; beginX < endX; beginX++) { //波浪形的x double wx = beginX * mDefaultAngularFrequency; //開始y的值通過公式計算 float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx)); canvas.drawLine(beginX, beginY, beginX, endY, wavePaint); waveY[beginX] = beginY; } //初始化前面波浪 前面波浪相對于后面波浪的偏移量 wavePaint.setColor(mFrontWaveColor); final int wave2Shift = (int) (mDefaultWaveLength / 4); for (int beginX = 0; beginX < endX; beginX++) { canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, endY, wavePaint); } //產生一個畫有一個位圖的渲染器 , // Shader.TileMode.REPEAT: 在x軸上面的平鋪模式、REPEAT:橫向和縱向的重復渲染器圖片,平鋪 //Shader.TileMode.CLAMP 渲染器超出原始邊界范圍,會復制范圍內邊緣染色 // 在x軸采用橫向和縱向平鋪。在y軸采用渲染器超出原始邊界范圍,會復制范圍內邊緣染色 mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); mViewPaint.setShader(mWaveShader); } @Override protected void onDraw(Canvas canvas) { //如果當前未顯示wave if (mShowWave && mWaveShader != null) { //還必須確定自定義控件的shader 不能為空 if (mViewPaint.getShader() == null) { mViewPaint.setShader(mWaveShader); } //先做縮放變換 mShaderMatrix.setScale( mWaveLengthRatio / DEFAULT_WAVE_LENGTH_RATIO,//x軸的縮放比例 mAmplitudeRatio / DEFAULT_AMPLITUDE_RATIO,//y軸的縮放該比例 0,//中心點x mDefaultWaterLevel);//中心點y //再做平移,這里注意下,是postTranslate ,不是setTranslate.是因為需要后乘 mShaderMatrix.postTranslate(mWaveShiftRatio * getWidth(),//在x軸移動的量 (DEFAULT_WATER_LEVEL_RATIO - mWaterLevelRatio) * getHeight()); //在y軸移動的量, //y軸上使用正數進行平移將向下移動圖像,而使用負數將向上移動圖像。 mWaveShader.setLocalMatrix(mShaderMatrix); //自定義控件的邊框寬度 float borderWidth = mBorderPaint == null ? 0f : mBorderPaint.getStrokeWidth(); switch (mShapeType) { case CIRCLE: if (borderWidth > 0) { //如果邊框的寬度大于0,則繪制出一個挨著自定義控件的圓形。 //該圓的中心肯定在自定義控件的中心。 canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, (getWidth() - borderWidth) / 2f - 1f, mBorderPaint); } //繪制自定義控件 float radius = getWidth() / 2f - borderWidth; //波形圖已經在mViewPaint 中的shader中了 canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, radius, mViewPaint); break; case SQUARE: if (borderWidth > 0) { canvas.drawRect( borderWidth / 2f, borderWidth / 2f, getWidth() - borderWidth / 2f - 0.5f, getHeight() - borderWidth / 2f - 0.5f, mBorderPaint); } canvas.drawRect(borderWidth, borderWidth, getWidth() - borderWidth, getHeight() - borderWidth, mViewPaint); break; } } else { mViewPaint.setShader(null); } } //*********************get和set開始********************************// /** * 得到偏移比例 * * @return 獲得偏移的比例 */ public float getWaveShiftRatio() { return mWaveShiftRatio; } /** * 設置波浪轉換偏移比例 * * @param waveShiftRatio waveShiftRatio 必須是 0 ~ 1.0的值,默認是0 */ public void setWaveShiftRatio(float waveShiftRatio) { if (mWaveShiftRatio != waveShiftRatio) { mWaveShiftRatio = waveShiftRatio; invalidate(); } } /** * 得到 水位比例 * * @return */ public float getWaterLevelRatio() { return mWaterLevelRatio; } /** * 設置水位比例 * * @param waterLevelRatio 必須是 0 ~ 1. 默認0.5f */ public void setWaterLevelRatio(float waterLevelRatio) { if (mWaterLevelRatio != waterLevelRatio) { mWaterLevelRatio = waterLevelRatio; invalidate(); } } /** * 得到振幅比例 * * @return */ public float getAmplitudeRatio() { return mAmplitudeRatio; } /** * 設置振幅比例 * * @param amplitudeRatio 默認是 0.05. 不能大于1 */ public void setAmplitudeRatio(float amplitudeRatio) { if (mAmplitudeRatio != amplitudeRatio) { mAmplitudeRatio = amplitudeRatio; invalidate(); } } /** * 得到寬度 * * @return */ public float getWaveLengthRatio() { return mWaveLengthRatio; } /** * 設置橫向波浪寬度的比例 * * @param waveLengthRatio 默認1 */ public void setWaveLengthRatio(float waveLengthRatio) { mWaveLengthRatio = waveLengthRatio; } public boolean isShowWave() { return mShowWave; } public void setShowWave(boolean showWave) { mShowWave = showWave; } /** * 設置 邊框的寬度和顏色 * * @param width * @param color */ public void setBorder(int width, int color) { if (mBorderPaint == null) { mBorderPaint = new Paint(); mBorderPaint.setAntiAlias(true); mBorderPaint.setStyle(Paint.Style.STROKE); } mBorderPaint.setColor(color); mBorderPaint.setStrokeWidth(width); invalidate(); } /** * 設置 波浪的顏色 * * @param behindWaveColor 后面波浪的顏色 * @param frontWaveColor 前面波浪的顏色 */ public void setWaveColor(int behindWaveColor, int frontWaveColor) { mBehindWaveColor = behindWaveColor; mFrontWaveColor = frontWaveColor; if (getWidth() > 0 && getHeight() > 0) { // need to recreate shader when color changed mWaveShader = null; createShader(); invalidate(); } } /** * 設置外形 * * @param shapeType */ public void setShapeType(ShapeType shapeType) { mShapeType = shapeType; invalidate(); } //*********************get和set結束********************************//}

WaveAnimatorHelper類,這個還有問題。太晚了。。睡覺去

public class WaveAnimatorHelper { /** * 動畫集合 */ private static AnimatorSet mAnimatorSet; private static List<Animator> animators; /** * 偏移量動畫 */ private static ObjectAnimator waveShiftAnim; /** * 水位高度動畫 */ private static ObjectAnimator waterLevelAnim; /** * 振幅角度動畫 */ private static ObjectAnimator amplitudeAnim; private static ObjectAnimator objectAnimator; /** * 是否暫停 */ private static boolean isPause = false; public enum ANIMATORTYPE { PROPERTYVALUES, ANIMATORSET } /** * 工具類的構造方法通常私有化 */ private WaveAnimatorHelper(ANIMATORTYPE type, float waterLevelStart, float waterLevelEnd, float waveShiftStart, float waveShiftEnd, float amplitudeStart, float amplitudeEnd, WaveView mWaveView, int duration) { //改變偏移量 if (type == ANIMATORTYPE.PROPERTYVALUES) {// PropertyValuesHolder waterLevelAnim = PropertyValuesHolder.ofFloat("waterLevelRatio", 0.0f, 0.5f); PropertyValuesHolder waterLevelAnim = PropertyValuesHolder.ofFloat("waterLevelRatio", waterLevelStart, waterLevelEnd);// PropertyValuesHolder waveShiftAnim = PropertyValuesHolder.ofFloat("waveShiftRatio", 0f, 1f); PropertyValuesHolder waveShiftAnim = PropertyValuesHolder.ofFloat("waveShiftRatio", waveShiftStart, waveShiftEnd);// PropertyValuesHolder amplitudeAnim = PropertyValuesHolder.ofFloat("amplitudeRatio", 0.0001f, 0.08f); PropertyValuesHolder amplitudeAnim = PropertyValuesHolder.ofFloat("amplitudeRatio", amplitudeStart, amplitudeEnd); objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mWaveView, waterLevelAnim, waveShiftAnim, amplitudeAnim); objectAnimator.setDuration(duration); objectAnimator.setRepeatMode(REVERSE); objectAnimator.setRepeatCount(INFINITE); objectAnimator.start(); } else { animators = new ArrayList<>(); waveShiftAnim = ObjectAnimator.ofFloat( mWaveView, "waveShiftRatio", waveShiftStart, waveShiftEnd); // 無限 循環 waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE); waveShiftAnim.setDuration(duration); //勻速線性差值器 waveShiftAnim.setInterpolator(new LinearInterpolator()); animators.add(waveShiftAnim);// 改變水位比例 waterLevelAnim = ObjectAnimator.ofFloat( mWaveView, "waterLevelRatio", waterLevelStart, waterLevelEnd); waterLevelAnim.setDuration(duration * 3); waterLevelAnim.setRepeatCount(ValueAnimator.INFINITE); waterLevelAnim.setRepeatMode(ValueAnimator.REVERSE); //減速差值器 waterLevelAnim.setInterpolator(new DecelerateInterpolator()); animators.add(waterLevelAnim);// 改變振幅比例 amplitudeAnim = ObjectAnimator.ofFloat( mWaveView, "amplitudeRatio", amplitudeStart, amplitudeEnd); amplitudeAnim.setRepeatCount(ValueAnimator.INFINITE); amplitudeAnim.setRepeatMode(ValueAnimator.REVERSE); amplitudeAnim.setDuration(duration * 2); amplitudeAnim.setInterpolator(new LinearInterpolator()); animators.add(amplitudeAnim); mAnimatorSet = new AnimatorSet(); mAnimatorSet.playTogether(animators); if (mAnimatorSet != null) { mAnimatorSet.start(); } } } /** * 通過ObjectAnimator.ofPropertyValuesHolder方式啟動動畫。3個動畫持續時間相同 * * @param waterLevelStart 水位開始位置 * @param waterLevelEnd 水位結束位置 * @param waveShiftStart 偏移開始位置 * @param waveShiftEnd 偏移結束位置 * @param amplitudeStart 振幅開始 * @param amplitudeEnd 振幅結束 * @param waveView 當前waveview * @param duration 持續時間 * @return */ public static WaveAnimatorHelper startAnimatorWithPropertyValuesHolder (float waterLevelStart, float waterLevelEnd, float waveShiftStart, float waveShiftEnd, float amplitudeStart, float amplitudeEnd, WaveView waveView, int duration) { return new WaveAnimatorHelper(ANIMATORTYPE.PROPERTYVALUES, waterLevelStart, waterLevelEnd, waveShiftStart, waveShiftEnd, amplitudeStart, amplitudeEnd, waveView, duration); } /** * 通過ObjectAnimator.ofPropertyValuesHolder方式啟動動畫。3個動畫持續時間相同 * * @param waterLevelStart 水位開始位置 * @param waterLevelEnd 水位結束位置 * @param waveShiftStart 偏移開始位置 * @param waveShiftEnd 偏移結束位置 * @param amplitudeStart 振幅開始 * @param amplitudeEnd 振幅結束 * @param waveView 當前waveview * @param duration 持續時間 * @return */ public static WaveAnimatorHelper startAnimatorWithAnimatorSet (float waterLevelStart, float waterLevelEnd, float waveShiftStart, float waveShiftEnd, float amplitudeStart, float amplitudeEnd, WaveView waveView, int duration) { return new WaveAnimatorHelper(ANIMATORTYPE.ANIMATORSET, waterLevelStart, waterLevelEnd, waveShiftStart, waveShiftEnd, amplitudeStart, amplitudeEnd, waveView, duration); } /** * 暫停PropertyValuesHolder動畫 */ @TargetApi(Build.VERSION_CODES.KITKAT) public static void stopAnimatorWithPropertyValuesHolder() { if (objectAnimator != null) { if (!isPause) { objectAnimator.pause(); isPause = true; } } } /** * 繼續PropertyValuesHolder動畫 */ @TargetApi(Build.VERSION_CODES.KITKAT) public static void resumePropertyValuesHolder() { if (objectAnimator != null) { if (isPause) { objectAnimator.resume(); isPause = false; return; } objectAnimator.resume(); } } public static void stopAnimationWithAnimatorSet(){ if(mAnimatorSet != null){ } }}

在activity中多了幾行代碼

waveView = (WaveView) findViewById(R.id.wave1); waveView.setShowWave(true); waveView.setWaveColor( Color.parseColor("#28f16d7a"), Color.parseColor("#3cf16d7a")); waveView.setShapeType(WaveView.ShapeType.SQUARE); WaveAnimatorHelper.startAnimatorWithAnimatorSet(0.0f, 0.4f, 0f, 1f, 0.0001f, 0.2f, waveView, 1000);

GitHub地址

CSDN地址


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 庄浪县| 连城县| 孝感市| 双柏县| 托克托县| 二连浩特市| 道孚县| 潍坊市| 翁源县| 桑植县| 通河县| 金山区| 饶阳县| 永寿县| 濮阳县| 常州市| 措美县| 钟祥市| 大足县| 公主岭市| 云安县| 晋州市| 兴化市| 濮阳市| 张家界市| 阿鲁科尔沁旗| 申扎县| 苗栗县| 刚察县| 岳普湖县| 蚌埠市| 邯郸县| 县级市| 灵宝市| 赞皇县| 台安县| 宁海县| 西乌| 韶山市| 黔江区| 高唐县|