iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android动画之小球拟合动画的示例分析
  • 275
分享到

Android动画之小球拟合动画的示例分析

android 2023-05-31 00:05:46 275人浏览 独家记忆
摘要

这篇文章给大家分享的是有关Android动画之小球拟合动画的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Android动画之小球拟合动画实例实现效果:动画组成:通过三阶贝塞尔曲线来拟合圆,拟合系数的由来

这篇文章给大家分享的是有关Android动画之小球拟合动画的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

Android动画之小球拟合动画实例

实现效果:

Android动画之小球拟合动画的示例分析

动画组成:

通过三阶贝塞尔曲线来拟合圆,拟合系数的由来,以及怎么选控制点.

利用画布canvas.translate,以及scale,rotate的方法,来渐变绘制的过程.

熟悉拟合过程.

不熟悉的话,先绘制辅助点的移动路线,对理解两个圆的分裂的拟合过程有好处.

package com.example.administrator.animationworkdemo.views;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PathMeasure;import android.util.AttributeSet;import android.view.View;import java.util.concurrent.CyclicBarrier;public class BallShapeChangeView extends View {  // 使用贝塞尔曲线来拟合圆的magic number  //C 是三阶贝塞尔曲线拟合 圆的 误差最小  获得控制点的参数.  private static final float C = 0.551915024494f;  private Paint mPaint;  private int mRadiusBig = 120, mRadiuSSMall = (int) (mRadiusBig / 2f), mWidth, mHeight, mMimWidth = (int) (mRadiusSmall * 2 * 3);  private float mFraction = 0, mFractionDegree = 0,       mLength, mDistanceBezier;  private Path mPathCircle, mPathBezier;  private ValueAnimator mValueAnimator;  private float[] mPointData = new float[8];// 4个数据点 顺时针排序,从左边开始  private float[] mPointCtrl = new float[16];// 8个控制点  private float[] mPos = new float[2];  private PathMeasure mPathMeasure;  private Path mPathBezier2;  public BallShapeChangeView(Context context, AttributeSet attrs) {    super(context, attrs);    mPaint = new Paint();    mPaint.setStyle(Paint.Style.FILL);    mPaint.setColor(0xFF7C191E);    mPaint.setAntiAlias(true);    mPathCircle = new Path();    mPathBezier = new Path();    mPathBezier2 = new Path();    mPathMeasure = new PathMeasure();    mValueAnimator = ValueAnimator.ofFloat(0, 1, 0);    mValueAnimator.setDuration(3000);    mValueAnimator.setRepeatCount(Integer.MAX_VALUE);    mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator animation) {        mFraction = (float) animation.getAnimatedValue();        mFractionDegree = animation.getAnimatedFraction();        invalidate();      }    });  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    // 为了能够更好的控制绘制的大小和位置,当然,初学者写死也是可以的    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    mWidth = MeasureSpec.getSize(widthMeasureSpec);    mHeight = MeasureSpec.getSize(heightMeasureSpec);    int widthMode = MeasureSpec.getMode(widthMeasureSpec);    int heightMode = MeasureSpec.getMode(heightMeasureSpec);    if (widthMode != MeasureSpec.AT_MOST && heightMode != MeasureSpec.AT_MOST) {      if (mWidth < mMimWidth)        mWidth = mMimWidth;      if (mHeight < mMimWidth)        mHeight = mMimWidth;    } else if (widthMeasureSpec != MeasureSpec.AT_MOST) {      if (mWidth < mMimWidth)        mWidth = mMimWidth;    } else if (heightMeasureSpec != MeasureSpec.AT_MOST) {      if (mHeight < mMimWidth)        mHeight = mMimWidth;    }    setMeasuredDimension(mWidth, mHeight);  }  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    // 通过mFraction来控制绘图的过程,这是常用的一种方式    canvas.translate(mWidth / 2, mHeight / 2);    canvas.scale(1, -1);    canvas.rotate(-360 * mFractionDegree);    setDoubleCirClePath();    canvas.drawPath(mPathCircle, mPaint);    if (mFraction < (1 / 3f)) {// 缩小大圆      setCirclePath();      canvas.drawPath(mPathCircle, mPaint);    } else if (mFraction < 3 / 4f) {// 画贝塞尔曲线      setBezierPath3();      canvas.drawPath(mPathBezier, mPaint);      canvas.drawPath(mPathBezier2, mPaint);    } else {// 画分离      //setLastBezierPath();      //canvas.drawPath(mPathBezier, mPaint);    }  }  private void setDoubleCirClePath() {    mPathCircle.reset();    if (mFraction < (1 / 3f)) {      mPathCircle.addCircle(-mRadiusSmall / 2f * mFraction * 3, 0, mRadiusSmall, Path.Direction.CW);      mPathCircle.addCircle(mRadiusSmall / 2f * mFraction * 3, 0, mRadiusSmall, Path.Direction.CW);    } else {      float distance = (mFraction - 1 / 3f) / (2 / 3f) * (mRadiusSmall * 2 + mRadiusSmall / 2f);      mPathCircle.addCircle(-mRadiusSmall / 2f - distance, 0, mRadiusSmall, Path.Direction.CW);      mPathCircle.addCircle(mRadiusSmall / 2f + distance, 0, mRadiusSmall, Path.Direction.CW);    }  }  // mFraction 0 ~ 1/3  private void setCirclePath() {    mPointData[0] = -mRadiusBig + mRadiusSmall / 2f * mFraction * 3f;    mPointData[1] = 0;    mPointData[2] = 0;    mPointData[3] = mRadiusBig - mRadiusBig / 2f * mFraction * 3f;//0到1 的三分之一 用来给大圆做效果;    mPointData[4] = mRadiusBig - mRadiusSmall / 2f * mFraction * 3f;    mPointData[5] = 0;    mPointData[6] = mPointData[2];    mPointData[7] = -mPointData[3];    mPointCtrl[0] = mPointData[0];// x轴一样    mPointCtrl[1] = mRadiusBig * C;// y轴向下的    mPointCtrl[2] = mPointData[2] - mRadiusBig * C;    mPointCtrl[3] = mPointData[3];// y轴一样    mPointCtrl[4] = mPointData[2] + mRadiusBig * C;    mPointCtrl[5] = mPointData[3];    mPointCtrl[6] = mPointData[4];    mPointCtrl[7] = mPointCtrl[1];    mPointCtrl[8] = mPointData[4];    mPointCtrl[9] = -mPointCtrl[1];    mPointCtrl[10] = mPointCtrl[4];    mPointCtrl[11] = mPointData[7];    mPointCtrl[12] = mPointCtrl[2];    mPointCtrl[13] = mPointData[7];    mPointCtrl[14] = mPointData[0];    mPointCtrl[15] = -mPointCtrl[1];    mPathCircle.reset();    mPathCircle.moveTo(mPointData[0], mPointData[1]);    mPathCircle.cubicTo(mPointCtrl[0], mPointCtrl[1], mPointCtrl[2], mPointCtrl[3], mPointData[2], mPointData[3]);    mPathCircle.cubicTo(mPointCtrl[4], mPointCtrl[5], mPointCtrl[6], mPointCtrl[7], mPointData[4], mPointData[5]);    mPathCircle.cubicTo(mPointCtrl[8], mPointCtrl[9], mPointCtrl[10], mPointCtrl[11], mPointData[6], mPointData[7]);    mPathCircle.cubicTo(mPointCtrl[12], mPointCtrl[13], mPointCtrl[14], mPointCtrl[15], mPointData[0], mPointData[1]);  }  // mFraction 1/3 ~ 3/4  private void setBezierPath3() {    mPointData[0] = -mRadiusSmall / 2 - (mFraction - 1 / 3f) * mRadiusBig * 2f;    if (mFraction < 2 / 3f) {      mPointData[1] = -mRadiusSmall;    } else {      mPointData[1] = -mRadiusSmall + (mFraction - 2 / 3f) * 3 * mRadiusSmall;    }    if (mFraction < 3 / 4f) {      mPointData[2] = 0;    } else {      //当分裂超过一定程度让结束点的位置变远      mPointData[2] = (mFraction - 3 / 4f) * 16 * mPointData[0];    }    //当动画执行进度大于2/3时,此时该点接近于0    mPointData[3] = -mRadiusBig + mFraction * mRadiusBig * 1.5f < -0.01f * mRadiusBig ? -mRadiusBig + mFraction * mRadiusBig * 1.5f : 0.01f * -mRadiusBig;    mPointData[4] = mPointData[2];    mPointData[5] = -mPointData[3];    mPointData[6] = mPointData[0];    mPointData[7] = -mPointData[1];    mPointCtrl[0] = mPointData[0] + mRadiusSmall;    mPointCtrl[1] = mPointData[3];    mPointCtrl[2] = mPointData[0] + mRadiusSmall;    mPointCtrl[3] = -mPointData[3];    mPathBezier.reset();    mPathBezier.moveTo(mPointData[0], mPointData[1]);    mPathBezier.quadTo(mPointCtrl[0], mPointCtrl[1], mPointData[2], mPointData[3]);    mPathBezier.lineTo(mPointData[4], mPointData[5]);    mPathBezier.quadTo(mPointCtrl[2], mPointCtrl[3], mPointData[6], mPointData[7]);    mPathBezier2.reset();    mPathBezier2.moveTo(-mPointData[0], mPointData[1]);    mPathBezier2.quadTo(-mPointCtrl[0], mPointCtrl[1], -mPointData[2], mPointData[3]);    mPathBezier2.lineTo(-mPointData[4], mPointData[5]);    mPathBezier2.quadTo(-mPointCtrl[2], mPointCtrl[3], -mPointData[6], mPointData[7]);  }  // mFraction 1/3 ~ 3/4  private void setBezierPath() {    mPathBezier.reset();    float distance = (2 * mRadiusSmall + mRadiusSmall / 2f) * mFraction;    //float topY = mRadiusSmall * (1 - 0.6f * mFraction);    float topY = mRadiusSmall - mRadiusSmall * (mFraction - 1 / 3f);    float distanceBezier = topY - distance * C * (0.5f + 0.5f * mFraction);    if (mDistanceBezier != 0 && distanceBezier < (mDistanceBezier)) {      distanceBezier = mDistanceBezier;    }    mPathBezier.moveTo(-distance, topY);    mPathBezier.cubicTo(-distance, distanceBezier, distance, distanceBezier, distance, topY);    if (mDistanceBezier == 0) {      mPathMeasure.setPath(mPathBezier, false);      mLength = mPathMeasure.getLength();      mPathMeasure.getPosTan(mLength / 2, mPos, null);      if (mPos[1] <= 8) {        mDistanceBezier = distanceBezier;        mPathBezier.reset();        mPathBezier.moveTo(-distance, topY);        mPathBezier.cubicTo(-distance, mDistanceBezier, distance, mDistanceBezier, distance, topY);        mPathBezier.lineTo(distance, -topY);        mPathBezier.cubicTo(distance, -mDistanceBezier, -distance, -mDistanceBezier, -distance, -topY);        mPathBezier.close();        return;      }    }    mPathBezier.lineTo(distance, -topY);    mPathBezier.cubicTo(distance, -distanceBezier, -distance, -distanceBezier, -distance, -topY);    mPathBezier.close();  }  // mFraction 3/4 ~ 1  private void setLastBezierPath() {    float x = -mRadiusSmall / 2f - (mFraction - 1 / 3f) / (2 / 3f) * (mRadiusSmall * 2 + mRadiusSmall / 2f);    mPathBezier.reset();    mPathBezier.moveTo(x, mRadiusSmall);    mPathBezier.quadTo(x, 0, x + mRadiusSmall + mRadiusSmall * (4 - mFraction * 4), 0);    mPathBezier.quadTo(x, 0, x, -mRadiusSmall);    mPathBezier.lineTo(x, mRadiusSmall);    mPathBezier.moveTo(-x, mRadiusSmall);    mPathBezier.quadTo(-x, 0, -x - mRadiusSmall - mRadiusSmall * (4 - mFraction * 4), 0);    mPathBezier.quadTo(-x, 0, -x, -mRadiusSmall);    mPathBezier.lineTo(-x, mRadiusSmall);    mPathBezier.close();  }  @Override  protected void onAttachedToWindow() {    super.onAttachedToWindow();    if (!mValueAnimator.isRunning())      mValueAnimator.start();  }  @Override  protected void onDetachedFromWindow() {    super.onDetachedFromWindow();    if (mValueAnimator.isRunning())      mValueAnimator.cancel();  }}

感谢各位的阅读!关于“Android动画之小球拟合动画的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Android动画之小球拟合动画的示例分析

本文链接: https://www.lsjlt.com/news/222417.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android动画之小球拟合动画的示例分析
    这篇文章给大家分享的是有关Android动画之小球拟合动画的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Android动画之小球拟合动画实例实现效果:动画组成:通过三阶贝塞尔曲线来拟合圆,拟合系数的由来...
    99+
    2023-05-31
    android
  • Android之小球自由碰撞动画示例
    目录前言1. add balls List2.ball parameter3. 判断是否有发生碰撞的小球4.application display前言 本文将基于Android对一个...
    99+
    2024-04-02
  • css3的动画特效之动画序列的示例分析
    这篇文章给大家分享的是有关css3的动画特效之动画序列的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先复习一下animation动画添加各种参数(1)infinite...
    99+
    2024-04-02
  • JavaScript结合Canvas绘画画运动小球
    目录1.实现思路2.静态效果3.总结前言: canvas是HTML5新增的元素,也被称为画布,可以结合javascript实现绘制各种图形,制作各种炫酷的动画效果,现在我们也来使用c...
    99+
    2024-04-02
  • css动画的示例分析
    这篇文章主要为大家展示了“css动画的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“css动画的示例分析”这篇文章吧。   CSS3动画是什么?  ...
    99+
    2024-04-02
  • JavaScript结合Canvas如何绘画画运动小球
    这篇文章给大家分享的是有关JavaScript结合Canvas如何绘画画运动小球的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.实现思路首先为了达到我们想要的效果,可以先创建一个构造函数。给构造函数添加对应的属...
    99+
    2023-06-29
  • Angular4.0动画操作的示例分析
    这篇文章主要为大家展示了“Angular4.0动画操作的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Angular4.0动画操作的示例分析”这篇文章吧...
    99+
    2024-04-02
  • Vue3过渡动画的示例分析
    这期内容当中小编将会给大家带来有关Vue3过渡动画的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。背景在我的 《Vue 3 开发企业级音乐 App》课程问答区,有个同学提了个问题,在歌手列表到歌手...
    99+
    2023-06-22
  • Bootstrap过渡动画的示例分析
    这篇文章主要为大家展示了“Bootstrap过渡动画的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Bootstrap过渡动画的示例分析”这篇文章吧。动...
    99+
    2024-04-02
  • loading动画特效的示例分析
    这篇文章给大家分享的是有关loading动画特效的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。代码示例<!DOCTYPE html> <ht...
    99+
    2024-04-02
  • Angular路由动画及高阶动画函数的示例分析
    小编给大家分享一下Angular路由动画及高阶动画函数的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、路由动画路由动画需要在host元数据中指定触发器。动画注意不要过多,否则适得其反。内容优先,引导用户去注意到...
    99+
    2023-06-15
  • Android高级动画篇之SVG矢量动画范例
    目录效果视频目录结构SVG常用指令初始化状态效果图制作静态SVG图型动画变换动画黏合引用解决低版本异常问题效果视频 目录结构 SVG常用指令 L :为从当前点绘制到直线给定的点,...
    99+
    2024-04-02
  • vue3中过渡动画的示例分析
    这篇文章主要介绍了vue3中过渡动画的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、vue中动画简单介绍在vue中如果一些过程不存在动画效果,则表现出来的结果是比...
    99+
    2023-06-29
  • Canvas帧动画吃苹果小游戏的示例分析
    这篇文章将为大家详细讲解有关Canvas帧动画吃苹果小游戏的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先看页面效果。下面四个按钮分别表示开始、结束、暂停、继续下面是帧动画图片素材:帧动画的实现...
    99+
    2023-06-09
  • Flutter封装组动画混合动画AnimatedGroup示例详解
    目录一、来源二、AnimatedGroup使用示例:三、AnimatedGroup源码最后一、来源 项目中遇到混合动画的情况,每次实现都需要生命一堆属性,让代码变得杂乱,难以维护。...
    99+
    2023-01-28
    Flutter封装AnimatedGroup Flutter封装组动画混合动画
  • CSS3动画实例分析
    这篇文章主要介绍“CSS3动画实例分析”,在日常操作中,相信很多人在CSS3动画实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”CSS3动画实例分析”的疑惑有所帮助!接...
    99+
    2024-04-02
  • jquery中animate动画持续运动的示例分析
    这篇文章给大家分享的是有关jquery中animate动画持续运动的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。如下所示:function fingers()...
    99+
    2024-04-02
  • Vue3之列表动画和状态动画示例详解
    目录概述示例解析列表动画状态动画总结概述 列表动画和状态动画都是增加用户体验的方法,当一个列表添加数据或者移除数据时,如果直接添加,突然显示,未免有些突兀,而且用户可能会不知道此时...
    99+
    2023-05-14
    Vue3 列表动画状态动画 Vue3 动画
  • Android实现移动小球和CircularReveal页面切换动画实例代码
    前言本文主要给大家介绍了关于Android如何实现移动小球和CircularReveal页面切换动画的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。效果图如下是在fragment中跳转activity实现的效果,...
    99+
    2023-05-30
    android 小球移动 circularreveal
  • Android怎么实现小球自由碰撞动画
    这篇文章主要介绍“Android怎么实现小球自由碰撞动画”,在日常操作中,相信很多人在Android怎么实现小球自由碰撞动画问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android怎么实现小球自由碰撞动画...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作