C++工具箱——动画类之透明度渐变 & 大小渐变
Posted 牧秦丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++工具箱——动画类之透明度渐变 & 大小渐变相关的知识,希望对你有一定的参考价值。
上一章介绍了如何基于计时器设计一个通用的动画基类,这次我们通过从 CFrameAnimation派生,得到两个动画类:透明度渐变动画类CFrameAnimation和窗口大小渐变类CFrameSizeAnimation类。首先假设我们有一个通用窗口CWnd:
namespace Util
class CWnd
public:
BOOL Initialize();
void SetWndPos(POINT pt);
void SetWndSize(SIZE size);
void SetWndAlpha(BYTE alpha);
// ...
;
/* namespace Util end here. */
那么我们相应的 CFrameBlendAnimation如下:
/**
* \\file frameblendanimation.h
* \\author arnozhang
* \\date 2012.9.4
* \\email zyfgood12@163.com
* \\brief 窗体透明度渐变动画类.
*/
#ifndef __FRAME_BLEND_ANIMATION_H__
#define __FRAME_BLEND_ANIMATION_H__
#include "frameanimation.h"
#include <vector>
using std::vector;
namespace Util
class CFrameBlendAnimation
: public CFrameAnimation<CFrameBlendAnimation>
public:
typedef vector<BYTE> BlendAlphas;
friend CFrameAnimation<CFrameBlendAnimation>;
// 设置透明度变动范围.
void SetBlendAlphas(const BlendAlphas& alphas);
// 设置透明度变动范围.
void SetBlendAlphas(BYTE* pAlphas, size_t nAlphaCnt);
private:
CFrameBlendAnimation(CWnd& targetFrame);
~CFrameBlendAnimation();
// 渐变处理器.
virtual void _AnimationHandler();
// 启动动画.
virtual bool _PrepareAnimation();
BlendAlphas m_blendAlphas;
DWORD m_dwAnimationStep;
int m_nCurrStep;
int m_nCurrFrameAlpha;
;
/*namespace Util ends here.*/
#endif /*__FRAME_BLEND_ANIMATION_H__*/
其实现如下:
#include "frameblendanimation.h"
using Util::CFrameBlendAnimation;
using Util::CWnd;
CFrameBlendAnimation::CFrameBlendAnimation(CWnd& targetFrame)
: CFrameAnimation(targetFrame)
, m_nCurrStep(0)
, m_nCurrFrameAlpha(0)
CFrameBlendAnimation::~CFrameBlendAnimation()
void CFrameBlendAnimation::SetBlendAlphas(const BlendAlphas& alphas)
m_blendAlphas.clear();
if (alphas.size() < 2)
return ;
m_blendAlphas.reserve(alphas.size());
m_blendAlphas = alphas;
void CFrameBlendAnimation::SetBlendAlphas(BYTE* pAlphas, size_t nAlphaCnt)
m_blendAlphas.clear();
if (nAlphaCnt < 2)
return ;
m_blendAlphas.reserve(nAlphaCnt);
m_blendAlphas.assign(pAlphas, pAlphas + nAlphaCnt);
void CFrameBlendAnimation::_AnimationHandler()
int startAlpha = m_blendAlphas[m_nCurrStep - 1];
int endAlpha = m_blendAlphas[m_nCurrStep];
// 是否是下降的方式.
BOOL bDesc = (endAlpha - startAlpha) < 0;
if (bDesc)
m_nCurrFrameAlpha -= m_dwAnimationStep;
if (m_nCurrFrameAlpha <= endAlpha)
m_nCurrFrameAlpha = endAlpha;
++m_nCurrStep;
else
m_nCurrFrameAlpha += m_dwAnimationStep;
if (m_nCurrFrameAlpha >= endAlpha)
m_nCurrFrameAlpha = endAlpha;
++m_nCurrStep;
m_targetFrame.SetWndAlpha(static_cast<BYTE>(m_nCurrFrameAlpha));
if (m_nCurrStep >= (int)m_blendAlphas.size())
// 动画完成.
_AnimationFinished();
bool CFrameBlendAnimation::_PrepareAnimation()
if (m_blendAlphas.size() <= 1)
return false;
m_nCurrStep = 1;
m_nCurrFrameAlpha = m_blendAlphas[0];
UINT uSumAlphas = 0;
for (size_t i = 1; i < m_blendAlphas.size(); ++i)
uSumAlphas += abs(m_blendAlphas[i] - m_blendAlphas[i - 1]);
m_dwAnimationStep = uSumAlphas / m_dwFrameCount;
return true;
我们可以看出,这个动画类支持任意多的透明度渐变,只需传入一个渐变范围的数组或者 vector即可。使用方法如下:
void Util::CWnd::SetAlphaAnimationTest()
BYTE alphas[] = 255, 50, 255;
Util::CFrameBlendAnimation& blendAnimation =
Util::CFrameBlendAnimation::GetAnimation(*this);
blendAnimation.SetBlendAlphas(alphas, sizeof(alphas) / sizeof(BYTE));
blendAnimation.SetFinishedCallback(
BIND_ANIMATION_FINISHED_PROC(CWnd, _OnBlendAnimationFinished)
);
blendAnimation.SetAnimationFrameCount(50);
blendAnimation.StartAnimation();
我们可以看到,先用 CFrameAnimation::GetAnimation 获取一个动画对象的引用,这个对象的生命周期不用我们操心。然后进行一系列设置,包括透明度范围、完成回调、以及动画帧数等,最终通过 StartAnimation这个方法即可启动动画。使用起来非常方便。
示例程序中附带了 CFrameSizeAnimation 类的具体实现和使用方法,在此就不一一罗列了。那么,后续可加入的扩展呢?我想到了以下的动画:
1、窗口位置更改;
2、窗口大小更改,只不过是从某一点发散出来成为一个大小合适的窗口;
3、窗口大小更改,只不过是把一个窗口最终收缩到一个点;
4、……
如果你感兴趣,可以自己补充一些动画类自己玩玩。示例程序下载请猛击此处:http://download.csdn.net/detail/zhangyafengcpp/4572443。
以上是关于C++工具箱——动画类之透明度渐变 & 大小渐变的主要内容,如果未能解决你的问题,请参考以下文章