贝塞尔曲线学习【1】
来源:互联网 发布:淘宝面试问题及答案 编辑:程序博客网 时间:2024/06/06 19:53
贝塞尔曲线学习【1】
今天学习了贝塞尔曲线的相关内容
特别感谢 http://blog.csdn.net/z82367825/article/details/51599245 博文。
具体的理论知识就不写了。
在此处记录下 修改过的 波浪图(由原来的一条增加为3条交替变化)。如下图所示。具体实现可以参考上面的文章。
这里是绘制了三条贝塞尔曲线组合而成的效果。代码如下:
package com.zero.bezier.widget.wave;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.graphics.Shader;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.View;import android.view.animation.Animation;import android.view.animation.LinearInterpolator;public class WaveView extends View { /** * 波峰 */ private float mWavePeak = 35f; /** * 波槽 */ private float mWaveTrough = 35f; /** * 水位 */ private float mWaveHeight = 350f; private Paint mPaintWave1; private Path mPathWave1; private int mWaterColorWave1 = 0x990000FF; private Paint mPaintWave2; private Path mPathWave2; private int mWaterColorWave2 = 0x550000FF; private Paint mPaintWave3; private Path mPathWave3; private int mWaterColorWave3 = 0x220000FF; public WaveView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public WaveView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public WaveView(Context context) { super(context); init(); } private void init() { mPathWave1 = new Path(); mPaintWave1 = new Paint(); mPaintWave1.setAntiAlias(true); //mPaintWave1.setStyle(Paint.Style.FILL); //mPaintWave1.setColor(mWaterColorWave1); //mPaintWave1.setColor(getResources().getColor(android.R.color.holo_blue_bright)); mPathWave2 = new Path(); mPaintWave2 = new Paint(); mPaintWave2.setAntiAlias(true); mPaintWave2.setStyle(Paint.Style.FILL); mPaintWave2.setColor(mWaterColorWave2); //mPaintWave2.setColor(getResources().getColor(android.R.color.holo_red_light)); mPathWave3 = new Path(); mPaintWave3 = new Paint(); mPaintWave3.setAntiAlias(true); mPaintWave3.setStyle(Paint.Style.FILL); mPaintWave3.setColor(mWaterColorWave3); //mPaintWave3.setColor(getResources().getColor(android.R.color.holo_green_light)); LinearGradient linearGradient = new LinearGradient( 0, 0, 720, 720, mWaterColorWave1, mWaterColorWave3, Shader.TileMode.CLAMP); mPaintWave1.setShader(linearGradient); } private float mWidth, mHeight; private PointF mWave1Start; private PointF mWave1Left1, mWave1Left2, mWave1First, mWave1Second, mWave1Right; private PointF mWave1ControlLeft1, mWave1ControlLeft2, mWave1ControlFirst, mWave1ControlSecond; private PointF mWave2Start; private PointF mWave2Left1, mWave2Left2, mWave2First, mWave2Second, mWave2Right; private PointF mWave2ControlLeft1, mWave2ControlLeft2, mWave2ControlFirst, mWave2ControlSecond; private PointF mWave3Start; private PointF mWave3Left1, mWave3Left2, mWave3First, mWave3Second, mWave3Right; private PointF mWave3ControlLeft1, mWave3ControlLeft2, mWave3ControlFirst, mWave3ControlSecond; private boolean mIsRunning = false; private boolean mHasInit = false; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (!mHasInit) { mWidth = w; mHeight = h; mHasInit = true; } super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!mIsRunning || !mHasInit) return; mPathWave1.reset(); mPathWave1.moveTo(mWave1Left1.x, mWave1Left1.y); mPathWave1.quadTo(mWave1ControlLeft1.x, mWave1ControlLeft1.y, mWave1Left2.x, mWave1Left2.y); mPathWave1.quadTo(mWave1ControlLeft2.x, mWave1ControlLeft2.y, mWave1First.x, mWave1First.y); mPathWave1.quadTo(mWave1ControlFirst.x, mWave1ControlFirst.y, mWave1Second.x, mWave1Second.y); mPathWave1.quadTo(mWave1ControlSecond.x, mWave1ControlSecond.y, mWave1Right.x, mWave1Right.y); mPathWave1.lineTo(mWave1Right.x, mHeight); mPathWave1.lineTo(mWave1Left1.x, mHeight); mPathWave1.lineTo(mWave1Left1.x, mWave1Left1.y); canvas.drawPath(mPathWave1, mPaintWave1); mPathWave2.reset(); mPathWave2.moveTo(mWave2Left1.x, mWave2Left1.y); mPathWave2.quadTo(mWave2ControlLeft1.x, mWave2ControlLeft1.y, mWave2Left2.x, mWave2Left2.y); mPathWave2.quadTo(mWave2ControlLeft2.x, mWave2ControlLeft2.y, mWave2First.x, mWave2First.y); mPathWave2.quadTo(mWave2ControlFirst.x, mWave2ControlFirst.y, mWave2Second.x, mWave2Second.y); mPathWave2.quadTo(mWave2ControlSecond.x, mWave2ControlSecond.y, mWave2Right.x, mWave2Right.y); mPathWave2.lineTo(mWave2Right.x, mHeight); mPathWave2.lineTo(mWave2Left1.x, mHeight); mPathWave2.lineTo(mWave2Left1.x, mWave2Left1.y); canvas.drawPath(mPathWave2, mPaintWave2); mPathWave3.reset(); mPathWave3.moveTo(mWave3Left1.x, mWave3Left1.y); mPathWave3.quadTo(mWave3ControlLeft1.x, mWave3ControlLeft1.y, mWave3Left2.x, mWave3Left2.y); mPathWave3.quadTo(mWave3ControlLeft2.x, mWave3ControlLeft2.y, mWave3First.x, mWave3First.y); mPathWave3.quadTo(mWave3ControlFirst.x, mWave3ControlFirst.y, mWave3Second.x, mWave3Second.y); mPathWave3.quadTo(mWave3ControlSecond.x, mWave3ControlSecond.y, mWave3Right.x, mWave3Right.y); mPathWave3.lineTo(mWave3Right.x, mHeight); mPathWave3.lineTo(mWave3Left1.x, mHeight); mPathWave3.lineTo(mWave3Left1.x, mWave3Left1.y); canvas.drawPath(mPathWave3, mPaintWave3); } private void reset() { mWave1Start = new PointF(-mWidth, mHeight - mWaveHeight); mWave1Left1 = new PointF(-mWidth, mHeight - mWaveHeight); mWave1Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight); mWave1First = new PointF(0, mHeight - mWaveHeight); mWave1Second = new PointF(mWidth / 2f, mHeight - mWaveHeight); mWave1Right = new PointF(mWidth, mHeight - mWaveHeight); mWave1ControlLeft1 = new PointF(mWave1Left1.x + mWidth / 4f, mWave1Left1.y + mWavePeak); mWave1ControlLeft2 = new PointF(mWave1Left2.x + mWidth / 4f, mWave1Left2.y - mWaveTrough); mWave1ControlFirst = new PointF(mWave1First.x + mWidth / 4f, mWave1First.y + mWavePeak); mWave1ControlSecond = new PointF(mWave1Second.x + mWidth / 4f, mWave1Second.y - mWaveTrough); mWave2Start = new PointF(-mWidth, mHeight - mWaveHeight); mWave2Left1 = new PointF(-mWidth, mHeight - mWaveHeight); mWave2Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight); mWave2First = new PointF(0, mHeight - mWaveHeight); mWave2Second = new PointF(mWidth / 2f, mHeight - mWaveHeight); mWave2Right = new PointF(mWidth, mHeight - mWaveHeight); mWave2ControlLeft1 = new PointF(mWave2Left1.x + mWidth / 4f, mWave2Left1.y + mWavePeak); mWave2ControlLeft2 = new PointF(mWave2Left2.x + mWidth / 4f, mWave2Left2.y - mWaveTrough); mWave2ControlFirst = new PointF(mWave2First.x + mWidth / 4f, mWave2First.y + mWavePeak); mWave2ControlSecond = new PointF(mWave2Second.x + mWidth / 4f, mWave2Second.y - mWaveTrough); mWave3Start = new PointF(-mWidth, mHeight - mWaveHeight); mWave3Left1 = new PointF(-mWidth, mHeight - mWaveHeight); mWave3Left2 = new PointF(-mWidth / 2f, mHeight - mWaveHeight); mWave3First = new PointF(0, mHeight - mWaveHeight); mWave3Second = new PointF(mWidth / 2f, mHeight - mWaveHeight); mWave3Right = new PointF(mWidth, mHeight - mWaveHeight); mWave3ControlLeft1 = new PointF(mWave3Left1.x + mWidth / 4f, mWave3Left1.y + mWavePeak); mWave3ControlLeft2 = new PointF(mWave3Left2.x + mWidth / 4f, mWave3Left2.y - mWaveTrough); mWave3ControlFirst = new PointF(mWave3First.x + mWidth / 4f, mWave3First.y + mWavePeak); mWave3ControlSecond = new PointF(mWave3Second.x + mWidth / 4f, mWave3Second.y - mWaveTrough); } private class WaveHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == ANIM_START) { reset(); startAnimWave1(); startAnimWave2(); startAnimWave3(); mIsRunning = true; } } } private WaveHandler mWaveHandler = new WaveHandler(); private static final int ANIM_START = 1; public void setRunning() { new Thread(new Runnable() { @Override public void run() { while (!mHasInit) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } mWaveHandler.sendEmptyMessage(ANIM_START); } }).start(); } private void startAnimWave1() { ValueAnimator valueAnimator = ValueAnimator.ofFloat(mWave1Start.x, 0); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setDuration(3000); valueAnimator.setRepeatCount(Animation.INFINITE); //动画效果重复// valueAnimator.setRepeatMode(Animation.RESTART); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mWave1Left1.x = (float) animation.getAnimatedValue(); mWave1Left2 = new PointF(mWave1Left1.x + mWidth / 2f, mHeight - mWaveHeight); mWave1First = new PointF(mWave1Left2.x + mWidth / 2f, mHeight - mWaveHeight); mWave1Second = new PointF(mWave1First.x + mWidth / 2f, mHeight - mWaveHeight); mWave1Right = new PointF(mWave1Second.x + mWidth / 2f, mHeight - mWaveHeight); mWave1ControlLeft1 = new PointF(mWave1Left1.x + mWidth / 4f, mWave1Left1.y + mWavePeak); mWave1ControlLeft2 = new PointF(mWave1Left2.x + mWidth / 4f, mWave1Left2.y - mWaveTrough); mWave1ControlFirst = new PointF(mWave1First.x + mWidth / 4f, mWave1First.y + mWavePeak); mWave1ControlSecond = new PointF(mWave1Second.x + mWidth / 4f, mWave1Second.y - mWaveTrough); invalidate(); } }); valueAnimator.start(); } private void startAnimWave2() { ValueAnimator valueAnimator1 = ValueAnimator.ofFloat(mWave2Start.x, 0); valueAnimator1.setInterpolator(new LinearInterpolator()); valueAnimator1.setDuration(3000); valueAnimator1.setRepeatCount(Animation.INFINITE); valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mWave2Left1.x = (float) animation.getAnimatedValue(); mWave2Left2 = new PointF(mWave2Left1.x + mWidth / 2f, mHeight - mWaveHeight); mWave2First = new PointF(mWave2Left2.x + mWidth / 2f, mHeight - mWaveHeight); mWave2Second = new PointF(mWave2First.x + mWidth / 2f, mHeight - mWaveHeight); mWave2Right = new PointF(mWave2Second.x + mWidth / 2f, mHeight - mWaveHeight); mWave2ControlLeft1 = new PointF(mWave2Left1.x + mWidth / 4f, mWave2Left1.y + mWavePeak); mWave2ControlLeft2 = new PointF(mWave2Left2.x + mWidth / 4f, mWave2Left2.y - mWaveTrough); mWave2ControlFirst = new PointF(mWave2First.x + mWidth / 4f, mWave2First.y + mWavePeak); mWave2ControlSecond = new PointF(mWave2Second.x + mWidth / 4f, mWave2Second.y - mWaveTrough); invalidate(); } }); valueAnimator1.setStartDelay(-1800); valueAnimator1.start(); } private void startAnimWave3() { ValueAnimator valueAnimator1 = ValueAnimator.ofFloat(mWave3Start.x, 0); valueAnimator1.setInterpolator(new LinearInterpolator()); valueAnimator1.setDuration(3000); valueAnimator1.setRepeatCount(Animation.INFINITE); valueAnimator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mWave3Left1.x = (float) animation.getAnimatedValue(); mWave3Left2 = new PointF(mWave3Left1.x + mWidth / 2f, mHeight - mWaveHeight); mWave3First = new PointF(mWave3Left2.x + mWidth / 2f, mHeight - mWaveHeight); mWave3Second = new PointF(mWave3First.x + mWidth / 2f, mHeight - mWaveHeight); mWave3Right = new PointF(mWave3Second.x + mWidth / 2f, mHeight - mWaveHeight); mWave3ControlLeft1 = new PointF(mWave3Left1.x + mWidth / 4f, mWave3Left1.y + mWavePeak); mWave3ControlLeft2 = new PointF(mWave3Left2.x + mWidth / 4f, mWave3Left2.y - mWaveTrough); mWave3ControlFirst = new PointF(mWave3First.x + mWidth / 4f, mWave3First.y + mWavePeak); mWave3ControlSecond = new PointF(mWave3Second.x + mWidth / 4f, mWave3Second.y - mWaveTrough); invalidate(); } }); valueAnimator1.setStartDelay(-800); valueAnimator1.start(); }}
此处只记录下自己探索的内容:
1、由一条曲线扩充为多条,是开了多个ValueAnimator来invalidate()视图。
2、为了制造视差,在另外两条曲线的ValueAnimator实例中设定了.setStartDelay()值,使动画的发生值滞后(如果设定正值)或者提前(如果设定负值)。此处,设定了负值,即相位提前,避免在第一个曲线动画开始后,其他曲线存在滞后显示的情况
3、绘制path时,替代使用solid颜色,而是使用gradient实现渐变色
4、下面要探索下,是否 可以只使用一个ValueAnimator即可实现多个贝塞尔曲线交叠显示
阅读全文
0 0
- 贝塞尔曲线学习【1】
- 贝塞尔曲线学习(1)
- 贝塞尔曲线学习
- SVG 贝塞尔曲线学习一
- SVG 贝塞尔曲线学习二
- SVG 贝塞尔曲线学习三
- 学习曲线
- 学习曲线
- 学习曲线
- 学习曲线
- 贝塞尔曲线1
- 学习曲线和遗忘曲线
- 曲线平滑-贝塞尔曲线
- Unity3D学习日记(三)贝塞尔曲线
- iOS贝塞尔曲线学习笔记(一)
- Html5 canvas学习2-圆 贝塞尔曲线
- 贝塞尔曲线
- 贝塞尔曲线
- ubuntu 下win7引导修复
- 某市高新区管委会车辆出入管理创新思路
- java关键字this的用法总结
- Red Hat 7.3 基于本地http搭建YUM
- SSH的统一应用
- 贝塞尔曲线学习【1】
- 'Navigator is deprecated and has been removed from this package. It can now be installed ' +
- magnitude函数
- 使用fastjson 替换springMvc默认的jackson
- UnityShader案例(六)——渐变纹理
- 解决Hibernate:could not initialize proxy
- 使用Nginx+Keepalived组建高可用负载平衡Web server集群
- [Shell]tr命令使用指南
- [Java]集合框架中值得注意的点