电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Android 使用cos和sin繪制復合曲線動畫

瀏覽:5日期:2022-09-20 14:59:05
前言

前兩周在開發新需求的時候,設計給了一份類似這樣的動畫:

Android 使用cos和sin繪制復合曲線動畫

看著不難,即使一遍看不懂,嘿嘿,不還有設計稿。

Android 使用cos和sin繪制復合曲線動畫

作為一個平時很少寫動畫的 Android 開發仔,看到一段段的緩入緩出曲線的設計稿時,我的心情是這樣的:

Android 使用cos和sin繪制復合曲線動畫

雖然,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 得出,最后改一下中心點。

總結

本次的動畫案例不難,在面對復合緩入緩出曲線的情形,我們可以拆成一段段,用 sin 或者 cos 去描述,這樣的好處是可以只使用一個屬性動畫,且可以循環播放。

如果你有更好的方案,歡迎評論區交流。

以上就是Android 使用cos和sin繪制復合曲線動畫的詳細內容,更多關于Android 繪制復合曲線動畫的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 五轴加工中心_数控加工中心_铝型材加工中心-罗威斯 | 防渗土工膜|污水处理防渗膜|垃圾填埋场防渗膜-泰安佳路通工程材料有限公司 | 空气弹簧|橡胶气囊|橡胶空气弹簧-上海松夏减震器有限公司 | 金属检测机_金属分离器_检针验针机_食品药品金属检探测仪器-广东善安科技 | 高中学习网-高考生信息学习必备平台 | 曙光腾达官网-天津脚手架租赁-木板架出租-移动门式脚手架租赁「免费搭设」 | 磁力加热搅拌器-多工位|大功率|数显恒温磁力搅拌器-司乐仪器官网 | 能量回馈_制动单元_电梯节能_能耗制动_深圳市合兴加能科技有限公司 | 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 一体化污水处理设备,一体化污水设备厂家-宜兴市福源水处理设备有限公司 | 存包柜厂家_电子存包柜_超市存包柜_超市电子存包柜_自动存包柜-洛阳中星 | 安全阀_弹簧式安全阀_美标安全阀_工业冷冻安全阀厂家-中国·阿司米阀门有限公司 | 顶呱呱交易平台-行业领先的公司资产交易服务平台 | 软文发布-新闻发布推广平台-代写文章-网络广告营销-自助发稿公司媒介星 | 洁净棚-洁净工作棚-无菌室-净化工程公司_北京卫护科技有限公司 | 上海律师咨询_上海法律在线咨询免费_找对口律师上策法网-策法网 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 智能家居全屋智能系统多少钱一套-小米全套价格、装修方案 | PCB设计,PCB抄板,电路板打样,PCBA加工-深圳市宏力捷电子有限公司 | 不锈钢拉手厂家|浴室门拉手厂家|江门市蓬江区金志翔五金制品有限公司 | SDI车窗夹力测试仪-KEMKRAFT方向盘测试仪-上海爱泽工业设备有限公司 | 锡膏喷印机-全自动涂覆机厂家-全自动点胶机-视觉点胶机-深圳市博明智控科技有限公司 | 杰恒蠕动泵-蠕动泵专业厂家-19年专注蠕动泵| 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 耐酸碱胶管_耐腐蚀软管总成_化学品输送软管_漯河利通液压科技耐油耐磨喷砂软管|耐腐蚀化学软管 | 便携式表面粗糙度仪-彩屏硬度计-分体式粗糙度仪-北京凯达科仪科技有限公司 | 重庆磨床过滤机,重庆纸带过滤机,机床伸缩钣金,重庆机床钣金护罩-重庆达鸿兴精密机械制造有限公司 | 不锈钢轴流风机,不锈钢电机-许昌光维防爆电机有限公司(原许昌光维特种电机技术有限公司) | 全自动包装秤_全自动上袋机_全自动套袋机_高位码垛机_全自动包装码垛系统生产线-三维汉界机器(山东)股份有限公司 | 超声波清洗机_细胞破碎仪_实验室超声仪器_恒温水浴-广东洁盟深那仪器 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 南京试剂|化学试剂|分析试剂|实验试剂|cas号查询-专业60年试剂销售企业 | 变色龙云 - 打包app_原生app_在线制作平台_短链接_ip查询 | 烟台螺纹,烟台H型钢,烟台钢材,烟台角钢-烟台市正丰金属材料有限公司 | 三效蒸发器_多效蒸发器价格_四效三效蒸发器厂家-青岛康景辉 | 黄石妇科医院_黄石东方女子医院_黄石东方妇产医院怎么样 | 棉服定制/厂家/公司_棉袄订做/价格/费用-北京圣达信棉服 | 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 等离子空气净化器_医用空气消毒机_空气净化消毒机_中央家用新风系统厂家_利安达官网 | 欧洲MV日韩MV国产_人妻无码一区二区三区免费_少妇被 到高潮喷出白浆av_精品少妇自慰到喷水AV网站 | 成都竞价托管_抖音代运营_网站建设_成都SEM外包-成都智网创联网络科技有限公司 |