Android实现 曲线路径动画

article/2025/10/24 11:11:38

本文参考
https://www.jianshu.com/p/fea4d1f6512a

概述

近期碰到曲线动画的实现问题,写本文记录下。

动画类似“剑与远征”游戏的金币动画,动画路径如下图:

思路

  1. 通过贝塞尔曲线计算出x和y的位置(各个点的位置需要自己微调)
    (此部分内容参考此文:https://www.jianshu.com/p/fea4d1f6512a)
  2. 通过ValueAnimator来实现动画

demo如下:

注意:
此demo使用到了屏幕的宽高,因此如果要demo显示正常,需要把状态栏显示透明,把acitionbar去掉。

源码

MainActivity.java

public class MainActivity extends AppCompatActivity {//uiprivate Button btnOne;private Button btnTwo;private Button btnAnim;//dataprivate int screenHeight;private int screenWidth;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏setContentView(R.layout.activity_main);screenHeight=getResources().getDisplayMetrics().heightPixels;screenWidth=getResources().getDisplayMetrics().widthPixels;initViews();}private void initViews() {btnOne = findViewById(R.id.btn_one);btnTwo = findViewById(R.id.btn_two);btnAnim = findViewById(R.id.btn_anim);final ValueAnimator valueAnimator=new ValueAnimator();valueAnimator.setDuration(2000);valueAnimator.setObjectValues(new PointF(0, 0));valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {PointF point = (PointF) animation.getAnimatedValue();btnAnim.setX(point.x);btnAnim.setY(point.y);}});btnOne.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {valueAnimator.setEvaluator(new TypeEvaluator() {@Override public Object evaluate(float fraction, Object startValue, Object endValue) {return BezierUtil.calculateBezierPointForQuadratic(fraction,new PointF(btnAnim.getLeft(), btnAnim.getTop()),new PointF(screenWidth, screenHeight/2),new PointF(btnAnim.getLeft(), screenHeight));}});valueAnimator.start();}});btnTwo.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {valueAnimator.setEvaluator(new TypeEvaluator() {@Override public Object evaluate(float fraction, Object startValue, Object endValue) {return BezierUtil.calculateBezierPointForCubic(fraction,new PointF(btnAnim.getLeft(), btnAnim.getTop()),new PointF(screenWidth, screenHeight/3),new PointF(0, screenHeight/3*2),new PointF(btnAnim.getLeft(), screenHeight));}});valueAnimator.start();}});}
}

BezierUtil.java

public class BezierUtil {/*** B(t) = (1 - t)^2 * P0 + 2t * (1 - t) * P1 + t^2 * P2, t ∈ [0,1]** @param t 曲线长度比例* @param p0 起始点* @param p1 控制点* @param p2 终止点* @return t对应的点*/public static PointF calculateBezierPointForQuadratic(float t, PointF p0, PointF p1, PointF p2) {PointF point = new PointF();float temp = 1 - t;point.x = temp * temp * p0.x + 2 * t * temp * p1.x + t * t * p2.x;point.y = temp * temp * p0.y + 2 * t * temp * p1.y + t * t * p2.y;return point;}/*** B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3, t ∈ [0,1]** @param t 曲线长度比例* @param p0 起始点* @param p1 控制点1* @param p2 控制点2* @param p3 终止点* @return t对应的点*/public static PointF calculateBezierPointForCubic(float t, PointF p0, PointF p1, PointF p2,PointF p3) {PointF point = new PointF();float temp = 1 - t;point.x = p0.x * temp * temp * temp+ 3 * p1.x * t * temp * temp+ 3 * p2.x * t * t * temp+ p3.x * t * t * t;point.y = p0.y * temp * temp * temp+ 3 * p1.y * t * temp * temp+ 3 * p2.y * t * t * temp+ p3.y * t * t * t;return point;}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_one"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="二阶贝塞尔曲线"/><Buttonandroid:id="@+id/btn_two"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="三阶贝塞尔曲线"/><Buttonandroid:id="@+id/btn_anim"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Anim"/>
</LinearLayout>

http://chatgpt.dhexx.cn/article/elOcdSDv.shtml

相关文章

WPF实现路径动画

让目标沿着一条给定的路径移动&#xff0c;使用DoubleAnimationUsingPath类实现。实现如下。 点击鼠标移动 实现代码如下&#xff1a;界面XAML <Grid x:Name"LayoutRoot"> <Grid.Resources> <PathGeometry x:Key"movingPath…

Houdini:最小白的路径动画

涉及节点&#xff1a;curve、constraints、follow path 涉及知识&#xff1a;路径动画、约束 提一嘴maya的路径动画&#xff1a;在constrain-->motion paths -->attach motion path中 一、模型准备 一个模型和一个curve曲线&#xff0c;分别在两个geometry里面&#…

UE5蓝图时间轴摄影机路径动画

1. 新建蓝图类Actor 2. 蓝图里添加Spline和Camera组件&#xff0c;另外添加一个Scene场景组件&#xff0c;可以把Camera拖到Scene的子级&#xff0c;这样做可以让Camera在沿着路径运动的时候自由更改旋转方向 3. 打开关卡蓝图&#xff0c;首先按键获取MovingLine的Camera视角&a…

html5 路径运动,探秘神奇的运动路径动画 Motion Path

CSS 中有一个非常有意思的模块 -- CSS Motion Path Module Level 1,翻译过来也就是运动路径。本文将对 motion path 一探究竟,通过本文,你可以了解到:什么是 CSS motion path 使用 CSS motion path 制作简单路径动画 使用 CSS motion path 制作复杂路径动画 什么是 CSS Mot…

canvas绘制折线路径动画

最近有读者加我微信咨询这个问题&#xff1a; 其中的效果是一个折线路径动画效果&#xff0c;如下图所示&#xff1a; 要实现以上路径动画&#xff0c;一般可以使用svg的动画功能。或者使用canvas绘制&#xff0c;结合路径数学计算来实现。 如果用canvas来绘制&#xff0c…

路径动画

工作日记&#xff0c;最近做项目遇到一个有意思的动画效果&#xff0c;路径动画&#xff0c;做一个demo&#xff0c;方便以后查阅&#xff0c;也供初学者借鉴&#xff01; 效果如下图&#xff1a; 效果分两步&#xff1a; 第一步是把书翻开&#xff0c;是一个贞动画&#xf…

openlayers实现路径动画

实现效果如下 主要代码 import {Feature} from ol; import {LineString, Point} from ol/geom; import {Icon, Stroke, Fill, Style} from ol/style; import {getVectorContext} from ol/render;// 路径动画图层 let traceSource new VectorSource({}); let moveLayer new…

咸鱼Maya笔记—路径动画

咸鱼Maya笔记—路径动画 创建路径动画 动画的创建方式有很多种&#xff0c;路径动画是其中的一种&#xff0c;Key关键帧的方式并不适用于所有的情况&#xff0c;有些特定的情况下我们就需要用到路径动画&#xff0c;它的创建方法如下 创建路径动画 &#xff08;如果你的maya菜…

CSS 路径动画

前言 最近看css大佬chokcoco的文章&#xff0c;看到了这篇 探秘神奇的运动路径动画 Motion Path 关于css路径动画的文章。 之前没学过&#xff0c;这里按照大佬的文章进行简单的学习。 Motion Path CSS Motion Path 规范主要包含以下几个属性&#xff1a; offset-path&…

AnimationPath路径动画实现详解

AnimationPath路径动画实现详解&#xff1a; 一、关联类图展示 二、实现详解 首先我们通过调用createAnimationPath方法来创建动画路径&#xff0c;即&#xff1a;通过起点、终点以及之间的时间步长来进行插值来保证动画的一个流畅度&#xff0c;然后将这些时间和点保存到一个…

Dotween Path 路径动画使用方法详解

Dotween对于路径动画部分的api我觉得注释的过少了&#xff0c;很多用法没有写清楚&#xff0c;这里我就对Dotween Path做一下详细说明 1、API Dotween对于路径动画就只提供了两个方法&#xff0c;一个是针对于世界坐标的&#xff0c;一个是针对于局部坐标的&#xff0c;本质上…

WPF路径动画

特此声明&#xff1a;本文为CSDN博主「田野上的风筝」&#xff0c;原文地址&#xff1a;https://blog.csdn.net/weixin_43100896/article/details/87899883。感谢大佬的总结&#xff0c; 下文为转载内容。 在WPF中实现动画并不是什么困难的事&#xff0c;因为WPF提供了动画模型…

10路径动画

using System.Collections; using System.Collections.Generic; using System.Linq; using DG.Tweening; using UnityEngine;public class PathMove : MonoBehaviour {public Transform[] pointList;void Start(){//select方法,直接得到值,查询要返回的目标数据 int[] numm {…

服务器连接超时是怎么回事呢?

服务器连接超时就是在程序默认的等待时间内没有得到服务器的响应。 网络连接超时可能的原因有那些呢&#xff1f; 1、网络断开&#xff0c;不过经常显示无法连接。网络阻塞&#xff0c;导致你不能在程序默认等待时间内得到回复数据包。 2、网络不稳定&#xff0c;网络无法完整…

服务器时间修改连接超时时间,服务器设置网络连接超时时间设置

服务器设置网络连接超时时间设置 内容精选 换一换 有以下几种现象:将制作好的SD卡插入开发者板并上电后,开发者板LED1与LED2灯状态信息异常。将制作好的SD卡插入开发者板,并通过USB方式连接Ubuntu服务器,上电、开发者板启动完成后,Ubuntu服务器无虚拟网卡信息。将制作好的…

修改服务器超时时间,服务器超时时间设置

服务器超时时间设置 内容精选 换一换 在压测过程中能够提供自身性能数据的施压目标机器。管理执行机的节点。CPTS为用户的测试工程提供管理能力,事务、压测任务、测试报告的内容在同一个测试工程内共享复用,您可以为不同的测试项目创建不同的测试工程。事务是指用户自定义的操…

FinalShell连接超时解决方法

输入ipconfig查看是否自动更改了ip地址 如果ip地址有变动&#xff0c;在shell中更改 查看是否打开了vm服务 快捷键&#xff1a;win X 选择“计算机管理&#xff08;G&#xff09;” 下滑找到vm服务&#xff0c;如若关闭打开即可 查看是否打开vm网络连接 右键点击属性,勾选所示…

finalshell连接超时怎么办

错误提示&#xff1a;java.net.ConnectException: Connection timed out: connect 在Linux中输入ip addr 来查看ip地址是否还在 如果没有的话重启虚拟机&#xff0c;出现ip地址再进行ssh连接

光猫显示连接isp服务器超时,光猫链接isp服务器超时

光猫链接isp服务器超时 内容精选 换一换 若已有连接后端服务器超过请求超时时间没有请求传输后,ELB会将其断开。根据负载均衡器与后端服务器链接的协议不同,系统默认超时时间也不同,系统默认的超时时间如下。TCP协议:默认超时时间为300s。UDP协议:默认超时时间为10s。HTTP…

服务器时间修改连接超时时间设置,云服务器连接超时时间设置

云服务器连接超时时间设置 内容精选 换一换 配置高防IP服务后,网站执行某些POST请求时,长时间等待后返回504错误,执行不成功。此问题是由于请求处理时间过长,已超过高防IP服务的连接阈值,高防IP服务主动断开连接。TCP默认连接超时时间为900s。HTTP/WebSocket、HTTPS/WebSo…