Path绘制动态的贝塞尔曲线、PathMeasure来绘制path动画
来源:互联网 发布:科比本赛季数据 编辑:程序博客网 时间:2024/05/17 02:17
上一篇的波浪曲线是左右重复平移,这次是每一帧绘制一条线,组成上下浮动的曲线,下面是效果图
public WaveView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(6); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); path = new Path();
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(200, 200, 90, paint); path.reset(); path.moveTo(waveLength / 2, startY); path.rQuadTo(waveLength / 2, -waveHeight, waveLength, 0); path.rQuadTo(waveLength / 2, waveHeight, waveLength, 0); canvas.drawPath(path, paint);
下面是通过属性动画来改变贝塞尔控制点
protected void startAnimation() { //通过属性动画计算高度 final ValueAnimator animator = ValueAnimator.ofInt(-waveHeight, waveHeight); animator.setDuration(4000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { waveHeight = (int) animation.getAnimatedValue(); postInvalidateDelayed(1); } }); animator.setRepeatMode(ValueAnimator.REVERSE); animator.start(); }
path的曲线动画,下面是效果图
//全部代码如下: private PathMeasure pathM; private Bitmap bitmap; private int bitHeight; private int bitWidth; private Rect rect; private Matrix matrix; public WaveView(Context context) { this(context, null); } public WaveView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(6); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); path = new Path(); //来个path计算器 pathM = new PathMeasure(); bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_music); bitHeight = bitmap.getHeight(); bitWidth = bitmap.getWidth(); } private Paint paint;//定义画笔 private int waveLength = 200;//定义波长度 private Path path;//曲线路径 private int waveHeight = 120;//定义波的高度 private int startY = 500;//起点的Y坐标 private static String TAG = "test"; private float fraction = 0.0f; private float[] position = new float[2]; private float[] tange = new float[2]; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(200, 200, 90, paint); path.reset(); path.moveTo(waveLength / 2, startY); path.rQuadTo(waveLength / 2, -waveHeight, waveLength, 0); path.rQuadTo(waveLength / 2, waveHeight, waveLength, 0); canvas.drawPath(path, paint); pathM.setPath(path, false); float length = pathM.getLength(); Log.i(TAG, "WaveView: 长度==" + length); boolean flag = pathM.getPosTan(fraction * length, position, tange); if (flag) { //开始绘制运行轨迹 canvas.drawBitmap(bitmap, position[0] - bitWidth, position[1] - bitHeight, paint); } } protected void computePercent() { ValueAnimator animator = ValueAnimator.ofFloat(0, 1.0f); animator.setDuration(4000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { fraction = (float) animation.getAnimatedValue(); Log.i(TAG, "onAnimationUpdate: 百分比==" + fraction); postInvalidateDelayed(5); } }); animator.start(); }
上面有点缺陷就是“音乐符号”的运动角度没有设置和调整,调整后的效果如右边所示:
public WaveView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(6); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); path = new Path(); //新增代码。来个path计算器 pathM = new PathMeasure(); bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_music); bitHeight = bitmap.getHeight(); bitWidth = bitmap.getWidth(); matrix=new Matrix(); } private Paint paint;//定义画笔 private int waveLength = 200;//定义波长度 private Path path;//曲线路径 private int waveHeight = 120;//定义波的高度 private int startY = 500;//起点的Y坐标 private static String TAG = "test"; private float fraction = 0.0f; private float[] position = new float[2]; private float[] tange = new float[2]; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(200, 200, 90, paint); path.reset(); path.moveTo(waveLength / 2, startY); path.rQuadTo(waveLength / 2, -waveHeight, waveLength, 0); path.rQuadTo(waveLength / 2, waveHeight, waveLength, 0); canvas.drawPath(path, paint); pathM.setPath(path, false); float length = pathM.getLength(); Log.i(TAG, "WaveView: 长度==" + length); boolean flag = pathM.getPosTan(fraction * length, position, tange); if (flag) { //开始绘制运行轨迹// canvas.drawBitmap(bitmap, position[0] - bitWidth, position[1] - bitHeight, paint); matrix.reset(); float degree = (float) (Math.atan2(tange[1], tange[0])*180f/Math.PI); matrix.postRotate(degree,bitmap.getWidth()/2,bitmap.getHeight()/2); matrix.postTranslate(position[0]-bitmap.getWidth()/2,position[1]-bitmap.getHeight()/2); canvas.drawBitmap(bitmap,matrix,paint); } } protected void computePercent() { ValueAnimator animator = ValueAnimator.ofFloat(0, 1.0f); animator.setDuration(4000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { fraction = (float) animation.getAnimatedValue(); Log.i(TAG, "onAnimationUpdate: 百分比==" + fraction); postInvalidateDelayed(5); } }); animator.start(); }
总结:还有一种比较好的测量 方式,直接返回matrix,这个matrix里面包含了delt x和y,以及tang角度。
boolean flag = pathM.getMatrix(fraction * length, matrix, PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG); if (flag) { canvas.drawBitmap(bitmap, matrix, paint); }
新测量方式的源码截取和解释如下
/** * Pins distance to 0 <= distance <= getLength(), and then computes the * corresponding matrix. Returns false if there is no path, or a zero-length * path was specified, in which case matrix is unchanged. * * @param distance The distance along the associated path * @param matrix Allocated by the caller, this is set to the transformation * associated with the position and tangent at the specified distance * @param flags Specified what aspects should be returned in the matrix. */ public boolean getMatrix(float distance, Matrix matrix, int flags) { return native_getMatrix(native_instance, distance, matrix.native_instance, flags); }
阅读全文
0 0
- Path绘制动态的贝塞尔曲线、PathMeasure来绘制path动画
- Path,PathMeasure与贝塞尔曲线
- Path绘制贝塞尔曲线和波浪waveView
- 使用Path绘制图形,和绘制一条动画曲线(跟踪动画)
- android自定义View创建一个Path绘制多边形,贝塞尔曲线,
- 清除之前绘制的path
- 用Path来绘制一些图形
- 用Path来绘制一些图形
- Android:使用PathMeasure绘制动画效果的搜索按钮
- Bezier曲线的动态绘制
- 可动态绘制PATH的VIEW,会动态显示整个绘制过程
- Android绘图:自定义View——路径(Path)、贝塞尔曲线(绘制可动的波浪线)、Bitmap
- Android开发之Path的高级用法用贝塞尔曲线绘制波浪线
- Android 绘图基础:Path(绘制三角形、贝塞尔曲线、正余弦)
- 绘制路径Path
- 绘制路径Path
- Path绘制虚线
- 正弦余弦曲线的绘制动画
- 走向大神之路的必备git命令操作
- 关于setTimeout()方法的第一个参数是否加双引号的问题
- 古文观止卷七_五柳先生傳_陶淵明
- SharedPreferences在多进程中的使用的问题
- environment setup
- Path绘制动态的贝塞尔曲线、PathMeasure来绘制path动画
- HDFS HA 架构分析
- 拜占庭将军问题
- UDP协议接收端的基本代码
- 中断循环体(学习)
- Lucene提高搜索排名(文档域加权)
- studio 快捷键和一些啥啥啥的
- 基于函数加密的.so加固学习笔记
- 从现在开始 还是下一秒开始