本发明涉及应用的加载动画技术领域,具体说是一种弧线变速运动的动画算法。
背景技术
现有的应用程序(例如app),在打开运行时,总会看到一个加载动画页面,以便在等待加载的过程中,用户可以知晓应用程序正在工作、加载的进度等信息。
常见的加载动画页面,有的是呈现一张静态图片,有的是呈现一组图片实现动画效果,有的是呈现一段短视频实现动画效果,为了凸显个性化,丰富加载动画页面的功能及动画效果,有必要对加载动画页面进行优化、再设计。
根据公司目前的开发计划,拟实现一种模拟能量守恒双摆球的动画效果,该动画效果作为新版app的加载动画页面。所述模拟能量守恒双摆球动画效果中,包括沿水平方向依次排列的多颗小球(通常是奇数个),这些小球中,最左侧和最右侧的小球交替的被弹出并回落,小球的移动轨迹为弧线,且移动速度不恒定,故需要专门设计相应的轨迹移动算法。
技术实现要素:
针对现有技术中存在的缺陷,本发明的目的在于提供一种弧线变速运动的动画算法,自定义控件,实现圆弧摆动的效果,模拟能量守恒球不断碰撞的动画效果,呈现全新的加载动画页面,凸显个性化及app,具一定扩展性,可修改制作其他样式的加载动画效果,提高开发效率。
为达到以上目的,本发明采取的技术方案是:
一种弧线变速运动的动画算法,其特征在于,包括如下步骤:
创建画布canvas,canvas由android系统提供,供用户在上面进行绘制,
在ondraw回调中,canvas.save()获取canvas保存的状态,
以画布中心为中心进行画布旋转,
创建一个新的绘制区域arcbounds做为缓存,并设置内边距mstrokeinset,
设置每次绘制时画笔mpaint的宽度mpaint.setstrokewidth和颜色mpaint.setcolor,创建画笔mpaint时刻一并创建绘制区域mtempbounds,绘制区域mtempbounds用于布局界面circlerotateactivity,
开始画圆弧canvas.drawarc,drawarc获取以下参数信息:
第一个参数为圆弧的形状和大小的范围,
第二个参数是设置圆弧是从哪个角度来绘画的,
第三个参数是设置圆弧扫过的角度,
第四个参数是设置圆弧在绘画的时候是否经过圆形,
第五个参数是定义的画笔mpaint,
最后再恢复到canvas最初的状态canvas.restoretocount(savecount)。
在上述技术方案的基础上,画布旋转角度mgrouprotation的计算方法如下:
mgrouprotation=((full_group_rotation/num_points)*renderprogress)+(full_group_rotation*(mrotationcount/num_points));
其中:
full_group_rotation是一次循环的角度,
num_points是循环总次数,
renderprogress是当前变化的进度,
mrotationcount是当前循环位置。
在上述技术方案的基础上,设置每次绘制时画笔mpaint的宽度mpaint.setstrokewidth时,调用getstrokewidth()计算特定屏幕下画线的宽度,具体计算方式为:
特定屏幕下画线的宽度等于设置的默认画线宽度*屏幕分辨率screendensity。
在上述技术方案的基础上,所述第一个参数,由createarcbounds(arcbounds,i)计算得出,确定圆弧的形状和大小范围,需要针对每个线确定下一个画布区域,创建临时的绘制区域arcbounds,其中intervalwidth+=getstrokewidth()/(i+1.0f)*1.5f两条线间区域差为上一个线宽度的1.5倍,再根据上一个绘制区域的位置和两条线间的区域就确定了新区域arcbounds的范围。
在上述技术方案的基础上,所述第二个参数,起点角度是mstartdegrees,分别加上180和360表示向左上方和右上方绘制。
在上述技术方案的基础上,所述第三个参数,代表扫过的角度,等于终点角度减去起点角度,即:mswipedegrees=menddegrees–mstartdegrees。
在上述技术方案的基础上,在circlerotateactivity界面中用loadingdrawable创建出一个背景mwhorldrawable并设置为mivwhorl控件的背景,
在该界面onstart()时调用mwhorldrawable.start(),
在该界面onstop()时调用mwhorldrawable.stop();
创建mwhorldrawable时传入了一个加载渲染器loadingrenderer,newwhorlloadingrenderer(this)对象。
在上述技术方案的基础上,whorlloadingrenderer继承loadingrenderer,
创建一个贝塞尔曲线的插补器fastoutslowininterpolator(),运动规律是由慢到快再到慢,fastoutslowininterpolator产生速度先慢再快最后再慢的变速值。
在上述技术方案的基础上,创建一个贝塞尔曲线的插补器fastoutslowininterpolator的具体包括:
执行newfastoutslowininterpolator(),
赋值给material_interpolator,
限定material_interpolator为privatestaticfinalinterpolator。
在上述技术方案的基础上,调用插补器通过如下方式:
创建动画监听器manimatorlistener,设置动画开始时的操作和动画过程中的操作,
动画过程中的的时候,onanimationrepeat方法会在动画在重复播放的时候被回调,storeoriginals()保存上一次绘制位置,mstartdegrees=menddegrees,设置下一次起点为上一次的终点;mrotationcount=(mrotationcount+1)%(num_points)重新设置当前循环位置,
动画开始的时候,mrotationcount=0,把当前循环位置置为0。
本发明所述的弧线变速运动的动画算法,自定义控件,实现圆弧摆动的效果,模拟能量守恒球不断碰撞的动画效果,呈现全新的加载动画页面,凸显个性化及app,具一定扩展性,可修改制作其他样式的加载动画效果,提高开发效率。
附图说明
本发明有如下附图:
图1本发明的流程图。
具体实施方式
以下结合附图对本发明作进一步详细说明。
如图1所示,本发明所述的弧线变速运动的动画算法,包括如下步骤:
创建画布canvas,canvas由android系统提供,供用户在上面进行绘制,
在ondraw回调中,canvas.save()获取canvas保存的状态,
以画布中心为中心进行画布旋转,
canvas.rotate(mgrouprotation,bounds.exactcenterx(),bounds.exactcentery()),
其中:
mgrouprotation为画布旋转角度,
bounds.exactcenterx(),bounds.exactcentery()为画布中心坐标,
创建一个新的绘制区域arcbounds做为缓存,并设置内边距mstrokeinset,设置内边距mstrokeinset的具体方式为:
在构造方法中,设置了默认的颜色值;setinsets((int)getwidth(),(int)getheight())再根据默认的宽高计算内边距mstrokeinset,可使动画居中,
设置每次绘制时画笔mpaint的宽度mpaint.setstrokewidth和颜色mpaint.setcolor,创建画笔mpaint时刻一并创建绘制区域mtempbounds,绘制区域mtempbounds用于布局界面circlerotateactivity,
开始画圆弧canvas.drawarc,drawarc获取以下参数信息:
第一个参数为圆弧的形状和大小的范围,
第二个参数是设置圆弧是从哪个角度来绘画的,
第三个参数是设置圆弧扫过的角度,
第四个参数是设置圆弧在绘画的时候是否经过圆形,
第五个参数是定义的画笔mpaint,
最后再恢复到canvas最初的状态canvas.restoretocount(savecount)。
在上述技术方案的基础上,画布旋转角度mgrouprotation的计算方法如下:
mgrouprotation=((full_group_rotation/num_points)*renderprogress)+(full_group_rotation*(mrotationcount/num_points));
其中:
full_group_rotation是一次循环的角度(一次循环所占角度),full_group_rotation=3.0f*degree_360,
num_points是循环总次数,默认num_points=5,
renderprogress是当前变化的进度,
mrotationcount是当前循环位置。
在上述技术方案的基础上,设置每次绘制时画笔mpaint的宽度mpaint.setstrokewidth时,调用getstrokewidth()计算特定屏幕下画线的宽度,具体计算方式为:
特定屏幕下画线的宽度等于设置的默认画线宽度*屏幕分辨率screendensity。
例如,可采用如下代码:
for(inti=0;i<mcolors.length;i++){
mpaint.setstrokewidth(getstrokewidth()/(i+1));
mpaint.setcolor(mcolors[i]);
canvas.drawarc(createarcbounds(arcbounds,i),mstartdegrees+degree_180*(i%2),mswipedegrees,false,mpaint);
},
其中:
mcolors为默认的颜色值,mcolors=default_colors。
default_colors中定义了三种颜色default_colors=newint[]{color.red,color.green,color.blue}。
canvas.drawarc涉及的参数如前所述,
第一个参数为圆弧的形状和大小的范围,由createarcbounds(arcbounds,i)计算得出,具体算法如下:
privaterectfcreatearcbounds(rectfsourcearcbounds,intindex){
rectfarcbounds=newrectf();
intintervalwidth=0;
for(inti=0;i<index;i++){
intervalwidth+=getstrokewidth()/(i+1.0f)*1.5f;
}
intarcboundsleft=(int)(sourcearcbounds.left+intervalwidth);
intarcboundstop=(int)(sourcearcbounds.top+intervalwidth);
intarcboundsright=(int)(sourcearcbounds.right-intervalwidth);
intarcboundsbottom=(int)(sourcearcbounds.bottom-intervalwidth);
arcbounds.set(arcboundsleft,arcboundstop,arcboundsright,arcboundsbottom);
returnarcbounds;
}
其中:确定圆弧的形状和大小范围,需要针对每个线确定下一个画布区域,创建临时的绘制区域arcbounds,其中intervalwidth+=getstrokewidth()/(i+1.0f)*1.5f两条线间区域差为上一个线宽度的1.5倍,再根据上一个绘制区域的位置和两条线间的区域就确定了新区域arcbounds的范围,
第二个参数是设置圆弧是从哪个角度来绘画的,起点角度是mstartdegrees,分别加上180和360表示向左上方和右上方绘制,上述实施例是加上180,即mstartdegrees+degree_180*(i%2),degree_180=180作为初始旋转角度,显然加上360是指mstartdegrees+degree_360*(i%2),degree_360=360作为初始旋转角度,
第三个参数是设置圆弧扫过的角度,mswipedegrees代表扫过的角度,等于终点角度减去起点角度,即:mswipedegrees=menddegrees–mstartdegrees,
第四个参数是设置圆弧在绘画的时候是否经过圆形,
第五个参数是定义的画笔mpaint。
在上述技术方案的基础上,在circlerotateactivity界面中用loadingdrawable创建出一个背景mwhorldrawable并设置为mivwhorl控件的背景,
在该界面onstart()时调用mwhorldrawable.start(),
在该界面onstop()时调用mwhorldrawable.stop();
用loadingdrawable创建背景mwhorldrawable的代码可如下:
loadingdrawablemwhorldrawable=newloadingdrawable(newwhorlloadingrenderer(this));
loadingdrawable是一个使用drawable来绘制loading动画的库,创建mwhorldrawable时传入了一个加载渲染器loadingrenderer,newwhorlloadingrenderer(this)对象。
在上述技术方案的基础上,whorlloadingrenderer继承loadingrenderer,
创建一个贝塞尔曲线的插补器fastoutslowininterpolator(),运动规律是由慢到快再到慢,fastoutslowininterpolator产生速度先慢再快最后再慢的变速值,
创建一个贝塞尔曲线的插补器fastoutslowininterpolator的具体包括:
执行newfastoutslowininterpolator(),
赋值给material_interpolator,
限定material_interpolator为privatestaticfinalinterpolator。
在使用动画animation或者animationset的时候,有一个interpolator插补器的属性。可以使用这个属性来修饰动画运动的速率。比如加速、先加速再加速等。
本发明中,调用插补器通过如下方式:
创建动画监听器manimatorlistener,设置动画开始时的操作和动画过程中的操作,
创建动画监听器manimatorlistener,
代码如下:
privatefinalanimator.animatorlistenermanimatorlistener=newanimatorlisteneradapter(){
动画过程中的的时候,onanimationrepeat方法会在动画在重复播放的时候被回调,storeoriginals()保存上一次绘制位置,mstartdegrees=menddegrees,设置下一次起点为上一次的终点;mrotationcount=(mrotationcount+1)%(num_points)重新设置当前循环位置,
代码如下:
@override
publicvoidonanimationrepeat(animatoranimator){
super.onanimationrepeat(animator);
storeoriginals();
mstartdegrees=menddegrees;
mrotationcount=(mrotationcount+1)%(num_points);
}
动画开始的时候,mrotationcount=0,把当前循环位置置为0;
代码如下:
@override
publicvoidonanimationstart(animatoranimation){
super.onanimationstart(animation);
mrotationcount=0;
}
}。
使用时,把创建的监听器manimatorlistener设置给mrenderanimator,这是android系统提供的一种属性动画,用来控制控件的动画。
本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。