• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2022-06-24 15:43 Aet 隐藏边栏 |   抢沙发  8 
文章评分 2 次,平均分 5.0

创建动画

窗口

  1. 这个内容的设计是,作为一个组件存在(DLL),其他一个地方,会在比较早的时机统一调用这些插件的同名接口。
  2. 调用的时候会创建UI对象,并在这个UI对象的初始化里面,创建下面的窗口对象,并指定该对象位置,调用该对象初始化函数InitControls,设置该对象的可见与否。

动画消息

  1. 在初始化InitControls这里,为目标控件添加相关动画消息:给背景图片添加了alpha相关的消息,给主窗口添加了pos相关的消息

通知

  1. 因为这个UI对象是的父类是实现了通知机制的,所以在收到自定义的通知的时候,就开始SHOW相关内容,触发动画。
  2. 同理,收到关于隐藏的自定义通知的时候,也是类似处理。
  3. 下面的AniShow就是启动动画。

触发展示

  1. 可以看到,把目标bkg对象,以及一些参数传了过去,创建了一个对象,把这个对象添加到了一个map里面,并返回了这个对象,通过这个SAlphaAni启动动画

  1. 触发动画,可以看到使用上面创建的那个对象的一些成员变量,具象化了一个临时的EventAlphaAnimateStartEx,然后调用FireEvent对目标控件触发目标消息

触发消失

  1. 上面的窗口里面有3个page,这里是第一个page点击了关闭后,就掉触发隐藏动画

  1. 创建了一个退场动画消息相关的对象,对象被添加到了map,然后返回了对象,然后通过StartAni调用FireEvent触发目标消息

动画事件

  1. 上面分析了,调用AniShow后最后会通过FireEvent触发目标消息,这个目标消息就是一开始AccelerateQualityWnd::InitControls里面对目标添加的EVT_POS_ANI_START_EX,而这个事件和OnMainLayPosAniEx函数绑定到了一起,可以看到EventPosAnimateStopEx绑定了同一个函数

  1. 只要触发了这两个事件中的一个,就会调用OnMainLayPosAniEx这个函数,分辨是哪个事件,是通过e->nValue,也就是一开始创建的时候传过去的atv_out和atv_back
  2. 每个动画在开始前会触发一个事件,在结束后触发一个事件。
    该动画效果是先改变背景的阿尔法值,然后改变窗口位置,并在出场结束后,启动了一个定时器,这是因为需要在一定时间后,开始改变关闭按钮的文案,让文案显示倒计时。
  3. 而隐藏的时候,值是atv_back,可以看到,开始事件里没有做事情,而结束事件里,启动了另一个动画,是对阿尔法值的改变。
    就是当改变背景阿尔法值的动画走完后,又启动一个新的动画,用来改变窗口位置

关于通知

  1. 这个g_pRequest的内容,是在CMainDlg的构造里面调用XunYouInitializeInterfaces传过去的CMainDlg对象
  2. 因为CMainDlg是继承自CXunYouRequestImpl,而CXunYouRequestImpl是继承自IXunYouRequest
  3. 所以别的模块调用了AsyncNotify,实质是调到了CMainDlg的AsyncNotify里面,然后使用PostMessageW发了WM_ASYNC_NOTIFY消息,而前两个参数被使用MAKEWPARAM打包成WPARAM
  4. 而在CMainDlg的消息映射里面,OnAsyncNotify映射了WM_ASYNC_NOTIFY消息
  5. 在OnAsyncNotify里面,遍历所有加载了的组件,找到对应的type,然后调用它的OnNotify,然后就到了上面的AccelerateQualityEvaluateUIComponent::OnNotify这里。

解析

ISwndContainer

  1. 抽象类,继承自一个抽象类ITimelineHandler

SWindow

  1. 包含了ISwndContainer对象

创建过程

  1. 传进去的是一个SWindow对象,用这个SWindow对象创建了SAlphaAni
  2. 执行了SAlphaAni对象的SAlphaAni

ITimelineHandler

  1. 抽象类,接口OnNextFrame

SAlphaAni

  1. 继承自一个抽象类ITimelineHandler,实现OnNextFrame
  2. StartAni触发开始动画事件,ISwndContainer
  3. StopAni,ISwndContainer
  4. OnNextFrame

SwndContainerImpl

  1. 继承自ISwndContainer和SWindow

分析

  1. 创建了一个动画事件对象,这个动画事件对象保存了目标控件对象,同时这个动画事件对象有个基类是ITimelineHandler
  2. 而目标控件对象,有个成员变量,叫ISwndContainer,这个ISwndContainer的基类也是ITimelineHandler
  3. 所以当调用这个StartAni的时候,除了触发这个动画开始事件,还把动画事件对象的this设置给了目标控件对象m_obj保存的ISwndContainer成员
  4. ISwndContainer成员拿个传过来的动画事件对象后,就在list里面查找,没找到,就添加到列表里面
  5. 而在SwndContainerImpl的OnNextFrame这个函数里面,会把这个列表拷出来一份,做一个循环调用,就是把每个存起来的动画事件对象的OnNextFrame调一遍
  6. 也就是,上一步会调到一开始创建的那个动画事件对象的OnNextFrame函数

  1. 可以看到,一个动画会按多少次完成,是按照我们设置的时间来算的,totaltime除以10,就是次数
  2. 每一次执行,都会创建一个EventAlphaAnimateStepEx对象,会记录id,value,以及当前的执行次数,然后对目标窗口去触发这个事件
  3. 然后,第一次启动的时候动画事件对象的时候,还启动了个定时器TIMER_NEXTFRAME

  1. 可见,这个定时器消息,是发给了hostwnd,然后在SHostWnd中响应的

  1. 当最后一步的时候,会在StopAni里面杀掉对应的定时器,然后会对目标控件对象触发一个EventAlphaAnimateStopEx的事件

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享