温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
  • 忘记密码?
登录注册×
获取短信验证码
其他方式登录
点击 登录注册 即表示同意 《亿速云用户服务条款》
  • 服务器
  • 数据库
  • 开发技术
  • 网络安全
  • 互联网科技
登 录 注册有礼
最新更新 网站标签 地图导航
产品
  • 首页 > 
  • 教程 > 
  • 开发技术 > 
  • Android怎么使用cos和sin绘制复合曲线动画

Android怎么使用cos和sin绘制复合曲线动画

发布时间:2021-03-17 14:02:47 来源:亿速云 阅读:293 作者:小新 栏目: 开发技术

这篇文章将为大家详细讲解有关Android怎么使用cos和sin绘制复合曲线动画,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在开发新需求的时候,设计给了一份类似这样的动画:

Android怎么使用cos和sin绘制复合曲线动画

看着不难,即使一遍看不懂,嘿嘿,不还有设计稿。

Android怎么使用cos和sin绘制复合曲线动画

作为一个平时很少写动画的 Android 开发仔,看到一段段的缓入缓出曲线的设计稿时,我的心情是这样的:

虽然,Android 动画默认的插值器 AccelerateDecelerateInterpolator 有这样缓入缓出的效果:

Android怎么使用cos和sin绘制复合曲线动画

我总不能一整个动画给它拆成4段动画来写,还别说,我第一次写的代码还真的是这么干的。

第一次分析

本着能少写一行绝不多写一字的原则,询问了大佬同事的意见,大佬大手一挥:PathInterpolator(后证实有问题)。

简单看了一下使用方式,需要使用 Path,再看了一眼,好家伙,有可能会用到贝塞尔曲线,放弃~

为了能够快速的解决问题,就使用了上面谈到的方案:

private fun animateTagView(tagView: TextView) {
 // [0,200]区间的动画 
 val valueAnimatorOne = ValueAnimator.ofInt(0, 200)
 valueAnimatorOne.addUpdateListener {
  val per = it.animatedValue as Int / 200f
  tagView.rotation = 4 * per
  tagView.scaleX = (1 - 0.1 * per).toFloat()
  tagView.scaleY = (1 - 0.1 * per).toFloat()
 }
 valueAnimatorOne.duration = 200
 // [200,560]区间的动画
 val valueAnimatorTwo = ValueAnimator.ofInt(200, 560)
 valueAnimatorTwo.addUpdateListener {
  val per = (it.animatedValue as Int - 200) / 360f
  tagView.rotation = 3 - 11 * per
  tagView.scaleX = (0.9 + 0.1 * per).toFloat()
  tagView.scaleY = (0.9 + 0.1 * per).toFloat()
 }
 valueAnimatorTwo.duration = 360
 // [560,840]区间的动画
 val valueAnimatorThree = ValueAnimator.ofInt(560, 840)
 valueAnimatorThree.addUpdateListener {
  val per = (it.animatedValue as Int - 560) / 280f
  tagView.rotation = -8 + 12 * per
  tagView.scaleX = (1 - 0.2 * per).toFloat()
  tagView.scaleY = (1 - 0.2 * per).toFloat()
 }
 valueAnimatorThree.duration = 280
 // [840,1000]的动画
 val valueAnimatorFour = ValueAnimator.ofInt(840, 1000)
 valueAnimatorFour.addUpdateListener {
  val per = (it.animatedValue as Int - 840) / 160f
  tagView.rotation = 4 - 4 * per
  tagView.scaleX = (0.8 + 0.2 * per).toFloat()
  tagView.scaleY = (0.8 + 0.2 * per).toFloat()
 }
 valueAnimatorFour.duration = 160
 // 使用AnimatorSet串行执行动画
 val animationSet = AnimatorSet()
 animationSet.playSequentially(valueAnimatorOne, valueAnimatorTwo, valueAnimatorThree, valueAnimatorFour)
 tagView.post {
  tagView.pivotX = 0f
  tagView.pivotY = ad_tag_two.measuredHeight.toFloat()
  animationSet.start()
 }
}

整个动画被我拆成了[0,200]、[200,560]、[560,840]和[840,1000]四段属性动画,因为产品说只需要播放一次,所以使用 AnimatorSet 将动画组装起来,就可以解决问题。

第二次分析

第一次得到的方案虽然能够解决问题,如果遇到循环播放,AnimatorSet 就不行了,有没有其他方案呢?

趁着周末的时间,学了一下 PathInterpolator,发现这个玩意也解决不了问题,或者说不好解决问题,虽然可以用三阶贝塞尔曲线分段画出上述曲线,但 PathInterpolator 要求起点和终点分别在 (0,0) 和 (1,1)。

既然插值器不行,可以试试估值器,但一个估值器也解决不了旋转和缩放两种动画,看来得靠 AnimatorUpdateListener 去解决问题。

回头想一下,插值器是将均匀的时间片段转化成加速或者减速的行为,我们也可以将均匀的时间片段转化成对应的曲线,只要做好两点:

使用线性的插值器 LinearInterpolator。
将上面的曲线拆分,通过不同的 sin 或者 cos 方法表达。
以旋转动画为例,拆成的 sin 函数:

Android怎么使用cos和sin绘制复合曲线动画

另外一段动画的函数可以参考代码:

override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 val tvContent = findViewById<TextView>(R.id.tv_content)
 val valueAnimatorOne = ValueAnimator.ofFloat(0.0f, 1.5f)
 valueAnimatorOne.addUpdateListener {
  // 通过对应的sin和cos设置rotation和scale
  val per = it.animatedValue as Float
  var rotation: Float = 0f
  var scale: Float = 0f
  if(per >= 0 && per < 0.2f){
   rotation = sin((per / 0.2f) * Math.PI.toFloat() - Math.PI.toFloat() / 2) * 1.5f + 1.5f
   scale = cos(per / 0.2f * Math.PI.toFloat()) * 0.05f + 0.95f
  }
  if(per >= 0.2f && per < 0.56f){
   rotation = sin(Math.PI.toFloat() / 2 + Math.PI.toFloat() * ( per - 0.2f) / 0.36f) * 5.5f - 2.5f
   scale = cos((per - 0.2f) / 0.36f * Math.PI.toFloat() + Math.PI.toFloat()) * 0.05f + 0.95f
  }
  if(per >= 0.56f && per < 0.84f){
   rotation = sin(Math.PI.toFloat() * (per - 0.56f) / 0.28f - Math.PI.toFloat() / 2) * 6f - 2f
   scale = cos((per - 0.56f) / 0.28f * Math.PI.toFloat()) * 0.1f + 0.9f
  }
  if(per in 0.84f..1f){
   rotation = sin(Math.PI.toFloat() / 2 + Math.PI.toFloat() * (per - 0.84f) / 0.16f ) * 2f + 2f
   scale = cos((per - 0.84f) / 0.16f * Math.PI.toFloat() + Math.PI.toFloat()) * 0.1f + 0.9f
  }
  // 设置停止时间
  if(per > 1f && per <= 1.5f){
   rotation = 0f
   scale = 1.0f
  }
  tvContent.rotation = rotation
  tvContent.scaleX = scale
  tvContent.scaleY = scale
 }
 // 设置线性插值器
 valueAnimatorOne.interpolator = LinearInterpolator()
 // 动画时间
 valueAnimatorOne.duration = 1500
 // 无线循环
 valueAnimatorOne.repeatCount = -1
 tvContent.post {
  // 设置中心点
  tvContent.pivotX = 0f
  tvContent.pivotY = tvContent.measuredHeight.toFloat()
  valueAnimatorOne.start()
 }
}

整个代码还是比较简单的,旋转动画曲线由 sin 得出,缩放由 cos 得出,最后改一下中心点。

关于“Android怎么使用cos和sin绘制复合曲线动画”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节
推荐阅读:
  1. Android LineChart绘制多条曲线的方法
  2. Android中如何使用EasingFunctions动画曲线库

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android 动画 cos
  • 上一篇新闻:
    R语言绘图布局的案例分析
  • 下一篇新闻:
    JavaScript深拷贝的注意事项

猜你喜欢

  • Android内存文件如何操作
  • 内存文件在Android中的应用场景
  • 如何在Android中使用内存文件
  • Android内存文件的优势与限制
  • 内存文件对Android性能的影响
  • 如何优化Android内存文件的使用
  • Android内存文件的读写技巧
  • 内存文件在Android中的安全性问题
  • Android内存文件的异常处理
  • 内存文件在Android中的多线程应用
最新资讯
  • iconv在RESTful API中的编码处理
  • 字符编码标准化iconv的自动化工具介绍
  • iconv与UTF-8编码的最佳实践分享
  • PHP iconv在PDF文档处理中的编码问题
  • 字符编码兼容性iconv的兼容测试框架
  • iconv在Web服务器配置中的编码应用
  • 字符编码转换iconv的性能瓶颈分析
  • PHP iconv对GBK编码的特殊处理
  • iconv在跨域请求中的编码处理技巧
  • 字符编码统一iconv与配置文件的整合
相关推荐
  • 使用python 绘制正态曲线
  • 使用Canvas怎么绘制一个贝赛尔曲线轨迹动画
  • 如何使用canvas绘制贝塞尔曲线
  • CSS中怎么绘制曲线图形及展示动画
  • 如何进行LSTM总结及sin与cos拟合应用
  • 如何进行RNN总结及sin与cos拟合应用
  • Android怎么利用贝塞尔曲线绘制动画
  • Android怎么实现动态曲线绘制
  • Android怎么用Canvas绘制贝塞尔曲线
  • 怎么用Python绘制loss曲线和准确率曲线

相关标签

android进阶 android应用 android9.0 android intent androidx android 入门 androidstudio android4.4 android面试 android10 android性能调优 android ant android 设计模式 xamarin android android组件化 设计模式 android androidsdk android canvas android8.0 android打包
AI

玻璃钢生产厂家六安动物玻璃钢雕塑优势定西人物玻璃钢雕塑安装青海人物玻璃钢雕塑价格苏州秋季商场美陈玻璃钢仿铜雕塑哪家强长宁区镜面玻璃钢雕塑多少钱运城景观园林玻璃钢卡通雕塑厂家朔州玻璃钢雕塑人物麒麟玻璃钢雕塑厦门生产玻璃钢雕塑厂家湛江玻璃钢卡通雕塑供应商家商丘玻璃钢景观雕塑哪家好固原玻璃钢雕塑价格异形玻璃钢园林雕塑商场秋季堆头美陈天津潜江玻璃钢人物雕塑重庆人物玻璃钢雕塑制作玻璃钢造型雕塑利润怎么样江油玻璃钢景观雕塑虹口区拉丝玻璃钢雕塑哪家好甘南户外玻璃钢雕塑重庆步行街玻璃钢雕塑定做价格攀枝花商场美陈陕西创意玻璃钢雕塑销售厂家商场美陈是什么普洱市玻璃钢雕塑批发广场玻璃钢动物雕塑供应商上海艺术商场美陈供应商东营玻璃钢雕塑制作厂家上海玻璃钢树造型雕塑小品制作香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化