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

风火轮 – 飞入动画效果

时间:2015-03-04 19:14:46      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:opencv drgraph 动画

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

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

1.  飞入效果

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

头文件

/**

 *@class TCbwAnimationEffect_ FlyIn

 *@brief 动画基类

 *

 * 处理飞入动画效果

 *@author 陈斌文

 *@version 1.0

 *@date 2015-03-04

 *@QQ: 282397369

 */

class TCbwAnimationEffect_FlyIn : publicTCbwAnimationEffect { // 飞入

         typedefTCbwAnimationEffect inherited;

         virtualTRect __fastcall BuildDisplayRect(OBJECTMAT * m);

public:

         __fastcallTCbwAnimationEffect_FlyIn();

         staticTCbwAnimationEffect * Build();

};

然后实现:

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

__fastcallTCbwAnimationEffect_FlyIn::TCbwAnimationEffect_FlyIn()

         :TCbwAnimationEffect() {

         EffectType= cetFlyIn;

}

 

TCbwAnimationEffect *TCbwAnimationEffect_FlyIn::Build() {

         returnnew TCbwAnimationEffect_FlyIn;

}

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

TRect __fastcallTCbwAnimationEffect_FlyIn::BuildDisplayRect(OBJECTMAT * m) {

         TPointstartPos(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;

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

                   /FPeriodLength;

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

                   /FPeriodLength;

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

         returnresult;

}

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

2.  界面处理

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

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

         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];

         returnselectedEffectItems;

}

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

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

技术分享                  技术分享

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

         intEffectOptionType; // 效果选项,

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

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

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

         intindex = -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];

                            boolshouldBeSelected = (item->ImageIndex == index);

                            if(item->Selected!= shouldBeSelected)

                                  item->Selected= shouldBeSelected;

                   }

         }

         boolhasItemFlag = (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;

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

         UnicodeStringcn = effectItem->ClassName();

         UnicodeStringprefix = "TCbwAnimationEffect_";

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

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

         if(destNode){

                   for(intoptionIndex = 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(inti = 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(inti = 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(inttype) {

         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;

 

         RECTdisplayRect = 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;

 

         TRestoreApplicationCurrentStatus(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);

         }

         deletebackData;

         deleteFPreviewBitmap;

         deletebitmap;

}

这下可以看到效果:

技术分享


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

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

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

风火轮 – 飞入动画效果

标签:opencv drgraph 动画

原文地址:http://blog.csdn.net/arwen/article/details/44062591

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