码迷,mamicode.com
首页 > 其他好文 > 详细

风火轮 – 飞入动画效果

时间:2015-03-04 18:40:36      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

在动画基类的基础上,再实现各种动画效果,只需专注于各种逻辑实现,倒也不是太难的事。

今天实现第二个动画效果-飞入。

  1. 飞入效果

代码很少,因为只需要确定不同时间的位置,故只重载BuildDisplayRect:

头文件

/**

* @class TCbwAnimationEffect_ FlyIn

* @brief 动画基类

*

* 处理飞入动画效果

* @author 陈斌文

* @version 1.0

* @date 2015-03-04

* @QQ: 282397369

*/

class TCbwAnimationEffect_FlyIn : public TCbwAnimationEffect { // 飞入

    typedef TCbwAnimationEffect inherited;

    virtual TRect __fastcall BuildDisplayRect(OBJECTMAT * m);

public:

    __fastcall TCbwAnimationEffect_FlyIn();

    static TCbwAnimationEffect * Build();

};

然后实现:

// ***************************** 飞入效果 **************************************

__fastcall TCbwAnimationEffect_FlyIn::TCbwAnimationEffect_FlyIn()

    : TCbwAnimationEffect() {

    EffectType = cetFlyIn;

}

 

TCbwAnimationEffect * TCbwAnimationEffect_FlyIn::Build() {

    return new TCbwAnimationEffect_FlyIn;

}

// BuildDisplayRect是根据索引确定相应位置

TRect __fastcall TCbwAnimationEffect_FlyIn::BuildDisplayRect(OBJECTMAT * m) {

    TPoint startPos(m->LeftTopPosition.x, m->LeftTopPosition.y),

        endPos(m->LeftTopPosition.x, m->LeftTopPosition.y);

    if (cedFromBottom == EffectOptionType || cedFromLeftBottom == EffectOptionType ||

        cedFromRightBottom == EffectOptionType) // 自底部

            startPos.y = FHeight;

    if (cedFromTop == EffectOptionType || cedFromLeftTop == EffectOptionType ||

        cedFromRightTop == EffectOptionType) // 自顶部

            startPos.y = -m->Mat.rows;

    if (cedFromLeft == EffectOptionType || cedFromLeftBottom == EffectOptionType ||

        cedFromLeftTop == EffectOptionType) // 自左侧

            startPos.x = -m->Mat.cols;

    if (cedFromRight == EffectOptionType || cedFromRightBottom == EffectOptionType ||

        cedFromRightTop == EffectOptionType) // 自右侧

            startPos.x = FWidth;

    int x = startPos.x + (endPos.x - startPos.x) * (FCurrentIndex + 1)

        / FPeriodLength;

    int y = startPos.y + (endPos.y - startPos.y) * (FCurrentIndex + 1)

        / FPeriodLength;

    TRect result(x, y, x + m->Mat.cols, y + m->Mat.rows);

    return result;

}

// ***************************** 飞入效果 **************************************

  1. 界面处理

现在到了处理界面的时候,因为在飞入效果中,还需要再设定效果选项。

在选择对象的时候,可以再顺带判断是否有动画项,简化处理,当只有一个动画项的时候再进行编辑处理。

    TCbwAnimationEffect * FCurrentEffectItem;

    vector<TCbwAnimationEffect *> FAllAnimationEffects;

    vector<TCbwAnimationEffect *> __fastcall GetSelectEffectItems();

////////////////////////////////////////////////////////////////////////////////////////

vector<TCbwAnimationEffect *> __fastcall TForm::GetSelectEffectItems() {

    vector<TCbwAnimationEffect *> selectedEffectItems;

    FCurrentEffectItem = NULL;

    for (int i = 0; i < cSelectedObjects->MetaNumber; ++i) {

        TCbwObject * object = cSelectedObjects->Meta(i);

        CBW_ITERATOR(vector<TCbwAnimationEffect *>, FAllAnimationEffects)

            if((*it)->ContainsObject(object)) {

                selectedEffectItems.push_back(*it);

                break;

            }

    }

    if(selectedEffectItems.size() == 1)

        FCurrentEffectItem = selectedEffectItems[0];

    return selectedEffectItems;

}

再通过SelectAnimationEffect(FCurrentEffectItem)完成界面按钮的控制。

再深入研究下PPT中的动画项效果选项,发现其有两部分:固定的序列项,即作为一个对象、整批发送、按段落三个选项,其余为各动画项相应的属性项。

技术分享 技术分享

因此,在基类中加入效果选项属性,100以内为相应选项,100: 作为一个对象,101:整批发送,102:按段落

    int EffectOptionType; // 效果选项,

这样可以兼容所有效果选项(应该不会超过100项的吧)

而各个类型的效果选项,可以硬编码实现,也可以配置实现。从灵活角度,当然是配置实现了,后续也有利于国际化语言包。

void __fastcall TForm::SelectAnimationEffect(TCbwAnimationEffect * effectItem) {

    int index = -1;

    if(effectItem)

        index = effectItem->EffectType - 1;

    for (int i = 0; i < Gallery_FlashEffect->GalleryGroups->Count; ++i) { // 确保只添加一次

        TdxRibbonGalleryGroup * group = Gallery_FlashEffect->GalleryGroups->Items[i];

        for (int j = group->Items->Count - 1; j >= 0; --j) {

            TdxRibbonGalleryGroupItem * item = group->Items->Items[j];

            bool shouldBeSelected = (item->ImageIndex == index);

            if(item->Selected != shouldBeSelected)

                 item->Selected = shouldBeSelected;

        }

    }

    bool hasItemFlag = (effectItem != NULL);

    Button_Flash_Preview->Enabled = hasItemFlag;

    Button_Flash_Effect->Enabled = hasItemFlag;

    Button_Flash_Effect->ItemLinks->Clear();

    if(!TGlobalVariables::XmlForStringResource || !effectItem)

        return;

    CbwXmlNode * effectNode = TGlobalVariables::XmlForStringResource->RootNode->NodeByName("Effect", true);

    if(!effectNode)

        return;

    UnicodeString basePath = THelper::File::GetApplicationPath() + effectNode->AttributeValueByName("path");

    UnicodeString cn = effectItem->ClassName();

    UnicodeString prefix = "TCbwAnimationEffect_";

    cn.Delete(1, prefix.Length());

    CbwXmlNode * destNode = effectNode->NodeByAttribute("name", cn);

    if(destNode) {

        for(int optionIndex = 0; optionIndex < destNode->ElementNumber; ++optionIndex) {

            CbwXmlNode * optionNode = destNode->Elements(optionIndex);

            TdxBarSeparator * sep = new TdxBarSeparator(Application->MainForm);

            Button_Flash_Effect->ItemLinks->Add()->Item = sep;

            sep->Caption = optionNode->AttributeValueByName("caption");

            for(int i = 0; i < optionNode->ElementNumber; ++i) {

                CbwXmlNode * itemNode = optionNode->Elements(i);

                TdxBarButton * button = TCbwDevExp::CreateMenuItem(Button_Flash_Effect,

                    actEffect, itemNode->AttributeValueByName("caption"), i, true, false,

                    basePath + itemNode->AttributeValueByName("glyph"));

            }

        }

}

    CbwXmlNode * baseNode = effectNode->NodeByName("optionItem");

    if(baseNode) {

        TdxBarSeparator * sep = new TdxBarSeparator(Application->MainForm);

        Button_Flash_Effect->ItemLinks->Add()->Item = sep;

        sep->Caption = baseNode->AttributeValueByName("caption");

        for(int i = 0; i < baseNode->ElementNumber; ++i) {

            if(i && effectItem->RelativeObjectNumber() == 1) // 单个对象,只有一项

                break;

            CbwXmlNode * itemNode = baseNode->Elements(i);

            TdxBarButton * button = TCbwDevExp::CreateMenuItem(Button_Flash_Effect,

                actEffect, itemNode->AttributeValueByName("caption"), 100 + i, true, false,

                basePath + itemNode->AttributeValueByName("glyph"));

        }

    }

}

配置文件大体如下,实现到哪个效果,再相应添加配置项:

技术分享

从网上再找相应的图标,放到res\effect目录下

技术分享

再加上相应的按钮处理

 

void __fastcall TForm::Button_Flash_PreviewClick(TObject *Sender)

{

PreviewCurrentEffect();

}

//---------------------------------------------------------------------------

 

 

void __fastcall TForm::actEffectExecute(TObject *Sender)

{

    int tag = THelper::Util::GetActionTag(Sender);

    ChangeCurrentEffect(tag);

}

//---------------------------------------------------------------------------

 

void __fastcall TForm::ChangeCurrentEffect(int type) {

    if(!FCurrentEffectItem)

        return;

    FCurrentEffectItem->EffectOptionType = type;

    PreviewCurrentEffect();

}

 

void __fastcall TForm::PreviewCurrentEffect() {

    if(!FCurrentEffectItem)

        return;

FCurrentEffectItem->RefreshAllObjects();

    FCurrentEffectItem->SetBounds(ScrollBox->Width, ScrollBox->Height);

    Graphics::TBitmap * bitmap = new Graphics::TBitmap; // bitmap将用于显示

    bitmap->PixelFormat = pf24bit;

    bitmap->Width = ScrollBox->Width;

    bitmap->Height = ScrollBox->Height;

 

    RECT displayRect = Rect(ScrollBox->HorzScrollBar->Position,

        ScrollBox->VertScrollBar->Position, ScrollBox->HorzScrollBar->Position +

        ScrollBox->Width, ScrollBox->VertScrollBar->Position +

        ScrollBox->Height);

 

    Graphics::TBitmap * FPreviewBitmap = new Graphics::TBitmap;

    FPreviewBitmap->PixelFormat = pf24bit;

    FPreviewBitmap->Width = PaintBox->Width;

    FPreviewBitmap->Height = PaintBox->Height;

    TCanvas * canvas = FPreviewBitmap->Canvas;

    canvas->Rectangle(0, 0, 10000, 10000);

    CBW_ITERATOR(CbwObjects, Objects)(*it)->Canvas = canvas;

 

    CBW_ITERATOR(CbwObjects, Objects) {

        TCbwObject * object = *it;

        if (!CanObjectBeVisible(object) || !object->CanContinueWithRect

            (displayRect, CBW_CONTINUE_DRAW) || object->Selected)

            continue;

        object->Draw();

    }

    PostPaint(canvas);

    bitmap->Canvas->CopyRect(Rect(0, 0, bitmap->Width, bitmap->Height), canvas,

        displayRect);

    CBW_ITERATOR(CbwObjects, Objects)(*it)->Canvas = PaintBox->Canvas;

 

    TRestore ApplicationCurrentStatus(TGraphApp::CurrentStatus, cfsAnimation);

    BYTE * backData = THelper::Graphics::GetBitmapData(bitmap);

    FCurrentEffectItem->First();

    while(!FCurrentEffectItem->Eof) {

        FCurrentEffectItem->Draw(ScrollBox->Handle, backData, bitmap->Width, bitmap->Height);

        FCurrentEffectItem->Next();

//        THelper::Util::Delay(40);

        Sleep(10);

    }

    delete backData;

    delete FPreviewBitmap;

    delete bitmap;

}

这下可以看到效果:

技术分享

发现一个小小问题,点击各效果选项,效果选项的按钮图标没有相应改变。再花2分钟应该能解决。

以后每天没事的时候,实现一两个PPT动画效果,貌似一个月能实现完成。

在这之后,再实现潮流、跑马灯等效果,可以控制LED屏了,值得搞下。

风火轮 – 飞入动画效果

标签:

原文地址:http://www.cnblogs.com/drgraph/p/4313682.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!