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++工具箱——动画类之透明度渐变 & 大小渐变的主要内容,如果未能解决你的问题,请参考以下文章

Android动画效果translatescalealpharotate详解

android中的动画有哪几类,它们的特点和区别是啥?

JS实现透明度渐变动画

android透明度渐变动画

android标题栏透明度渐变

WPF实现渐变淡入淡出的动画效果